Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Dec 2019 18:39:55 +0000 (10:39 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Dec 2019 18:39:55 +0000 (10:39 -0800)
Pull EFI fixes from Ingo Molnar:
 "Protect presistent EFI memory reservations from kexec, fix EFIFB early
  console, EFI stub graphics output fixes and other misc fixes."

* 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi: Don't attempt to map RCI2 config table if it doesn't exist
  efi/earlycon: Remap entire framebuffer after page initialization
  efi: Fix efi_loaded_image_t::unload type
  efi/gop: Fix memory leak in __gop_query32/64()
  efi/gop: Return EFI_SUCCESS if a usable GOP was found
  efi/gop: Return EFI_NOT_FOUND if there are no usable GOPs
  efi/memreserve: Register reservations as 'reserved' in /proc/iomem

1894 files changed:
.gitattributes
.mailmap
Documentation/admin-guide/device-mapper/dm-integrity.rst
Documentation/admin-guide/device-mapper/index.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/arm/microchip.rst
Documentation/core-api/genalloc.rst
Documentation/core-api/kernel-api.rst
Documentation/dev-tools/kcov.rst
Documentation/dev-tools/kselftest.rst
Documentation/dev-tools/kunit/index.rst
Documentation/dev-tools/kunit/kunit-tool.rst [new file with mode: 0644]
Documentation/dev-tools/kunit/start.rst
Documentation/dev-tools/kunit/usage.rst
Documentation/devicetree/bindings/arm/amlogic.yaml
Documentation/devicetree/bindings/arm/atmel-at91.yaml
Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt [deleted file]
Documentation/devicetree/bindings/arm/cpus.yaml
Documentation/devicetree/bindings/arm/fsl.yaml
Documentation/devicetree/bindings/arm/marvell/ap80x-system-controller.txt [moved from Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt with 91% similarity]
Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.txt [deleted file]
Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mrvl/mrvl.txt [deleted file]
Documentation/devicetree/bindings/arm/mrvl/mrvl.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt [deleted file]
Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/arm/omap/prm-inst.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/realtek.yaml
Documentation/devicetree/bindings/arm/renesas,prr.txt [deleted file]
Documentation/devicetree/bindings/arm/renesas,prr.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/arm/renesas.yaml
Documentation/devicetree/bindings/arm/rockchip.yaml
Documentation/devicetree/bindings/arm/sunxi.yaml
Documentation/devicetree/bindings/arm/sunxi/sunxi-mbus.txt
Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml
Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml
Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt
Documentation/devicetree/bindings/crypto/allwinner,sun4i-a10-crypto.yaml
Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/ddr/lpddr2-timings.txt [moved from Documentation/devicetree/bindings/lpddr2/lpddr2-timings.txt with 100% similarity]
Documentation/devicetree/bindings/ddr/lpddr2.txt [moved from Documentation/devicetree/bindings/lpddr2/lpddr2.txt with 96% similarity]
Documentation/devicetree/bindings/ddr/lpddr3-timings.txt [new file with mode: 0644]
Documentation/devicetree/bindings/ddr/lpddr3.txt [new file with mode: 0644]
Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml
Documentation/devicetree/bindings/display/bridge/anx6345.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/display/msm/gmu.txt
Documentation/devicetree/bindings/display/msm/mdp5.txt
Documentation/devicetree/bindings/display/panel/ronbo,rb070d30.yaml
Documentation/devicetree/bindings/dma/allwinner,sun4i-a10-dma.yaml
Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml
Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml
Documentation/devicetree/bindings/i2c/allwinner,sun6i-a31-p2wi.yaml
Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml
Documentation/devicetree/bindings/iio/adc/allwinner,sun8i-a33-ths.yaml
Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-a10-ic.yaml
Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
Documentation/devicetree/bindings/interrupt-controller/mrvl,intc.txt
Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
Documentation/devicetree/bindings/media/allwinner,sun4i-a10-ir.yaml
Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt [deleted file]
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/allwinner,sun4i-a10-ts.yaml
Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml
Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
Documentation/devicetree/bindings/net/allwinner,sun4i-a10-mdio.yaml
Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml
Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml
Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml
Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml
Documentation/devicetree/bindings/nvmem/amlogic-efuse.txt
Documentation/devicetree/bindings/phy/allwinner,sun6i-a31-mipi-dphy.yaml
Documentation/devicetree/bindings/phy/phy-mmp3-usb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
Documentation/devicetree/bindings/power/qcom,rpmpd.txt
Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml
Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt [new file with mode: 0644]
Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt
Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml
Documentation/devicetree/bindings/reset/brcm,brcmstb-reset.txt
Documentation/devicetree/bindings/reset/qcom,aoss-reset.txt [deleted file]
Documentation/devicetree/bindings/reset/qcom,aoss-reset.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/reset/qcom,pdc-global.txt [deleted file]
Documentation/devicetree/bindings/reset/qcom,pdc-global.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/reset/renesas,rst.txt
Documentation/devicetree/bindings/reset/uniphier-reset.txt
Documentation/devicetree/bindings/rtc/allwinner,sun4i-a10-rtc.yaml
Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
Documentation/devicetree/bindings/serio/allwinner,sun4i-a10-ps2.yaml
Documentation/devicetree/bindings/soc/fsl/rcpm.txt
Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt
Documentation/devicetree/bindings/soc/rockchip/grf.txt
Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml
Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml
Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml
Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
Documentation/devicetree/bindings/spi/allwinner,sun4i-a10-spi.yaml
Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml
Documentation/devicetree/bindings/sram/qcom,ocmem.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/thermal/qcom-tsens.txt [deleted file]
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
Documentation/devicetree/bindings/timer/allwinner,sun4i-a10-timer.yaml
Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml
Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
Documentation/devicetree/bindings/timer/renesas,tmu.txt
Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml
Documentation/devicetree/bindings/vendor-prefixes.yaml
Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
Documentation/driver-api/thermal/sysfs-api.rst
Documentation/filesystems/erofs.txt
Documentation/filesystems/overlayfs.rst [moved from Documentation/filesystems/overlayfs.txt with 99% similarity]
Documentation/process/coding-style.rst
Documentation/scsi/smartpqi.txt
Documentation/translations/it_IT/process/coding-style.rst
Documentation/translations/zh_CN/process/coding-style.rst
Documentation/virt/kvm/api.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/include/asm/mmzone.h
arch/alpha/include/asm/pgalloc.h
arch/alpha/include/asm/pgtable.h
arch/alpha/mm/init.c
arch/arc/Kconfig
arch/arc/Makefile
arch/arc/boot/dts/axc001.dtsi
arch/arc/boot/dts/axs101.dts
arch/arc/boot/dts/axs103_idu.dts
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/boot/dts/haps_hs.dts
arch/arc/boot/dts/haps_hs_idu.dts
arch/arc/boot/dts/nsim_700.dts
arch/arc/boot/dts/nsim_hs.dts [deleted file]
arch/arc/boot/dts/nsim_hs_idu.dts [deleted file]
arch/arc/configs/haps_hs_defconfig
arch/arc/configs/haps_hs_smp_defconfig
arch/arc/configs/nsim_700_defconfig
arch/arc/configs/nsim_hs_defconfig [deleted file]
arch/arc/configs/nsim_hs_smp_defconfig [deleted file]
arch/arc/include/asm/cache.h
arch/arc/include/asm/entry-compact.h
arch/arc/include/asm/jump_label.h [new file with mode: 0644]
arch/arc/include/asm/mmu.h
arch/arc/include/asm/mmu_context.h
arch/arc/include/asm/pgtable.h
arch/arc/kernel/Makefile
arch/arc/kernel/jump_label.c [new file with mode: 0644]
arch/arc/kernel/unwind.c
arch/arc/mm/tlb.c
arch/arc/mm/tlbex.S
arch/arc/plat-sim/platform.c
arch/arm/Kconfig
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-baltos.dtsi
arch/arm/boot/dts/am335x-bone-common.dtsi
arch/arm/boot/dts/am335x-boneblue.dts
arch/arm/boot/dts/am335x-chiliboard.dts
arch/arm/boot/dts/am335x-cm-t335.dts
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am335x-guardian.dts
arch/arm/boot/dts/am335x-igep0033.dtsi
arch/arm/boot/dts/am335x-lxm.dts
arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi
arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts
arch/arm/boot/dts/am335x-netcan-plus-1xx.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-netcom-plus-2xx.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-netcom-plus-8xx.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-osd3358-sm-red.dts
arch/arm/boot/dts/am335x-pcm-953.dtsi
arch/arm/boot/dts/am335x-pdu001.dts
arch/arm/boot/dts/am335x-pepper.dts
arch/arm/boot/dts/am335x-pocketbeagle.dts
arch/arm/boot/dts/am335x-regor.dtsi
arch/arm/boot/dts/am335x-sancloud-bbe.dts
arch/arm/boot/dts/am335x-shc.dts
arch/arm/boot/dts/am335x-sl50.dts
arch/arm/boot/dts/am335x-wega.dtsi
arch/arm/boot/dts/am33xx-l4.dtsi
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am3517.dtsi
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am437x-gp-evm.dts
arch/arm/boot/dts/am437x-l4.dtsi
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts
arch/arm/boot/dts/am57xx-beagle-x15-revc.dts
arch/arm/boot/dts/armada-38x.dtsi
arch/arm/boot/dts/armada-xp-98dx3236.dtsi
arch/arm/boot/dts/armada-xp-db-xc3-24g4xg.dts
arch/arm/boot/dts/armada-xp.dtsi
arch/arm/boot/dts/aspeed-ast2500-evb.dts
arch/arm/boot/dts/aspeed-ast2600-evb.dts
arch/arm/boot/dts/aspeed-bmc-arm-stardragon4800-rep2.dts
arch/arm/boot/dts/aspeed-bmc-facebook-cmm.dts
arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts
arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-inspur-fp5280g2.dts
arch/arm/boot/dts/aspeed-bmc-inspur-on5263m5.dts
arch/arm/boot/dts/aspeed-bmc-intel-s2600wf.dts
arch/arm/boot/dts/aspeed-bmc-lenovo-hr630.dts
arch/arm/boot/dts/aspeed-bmc-lenovo-hr855xg2.dts
arch/arm/boot/dts/aspeed-bmc-opp-lanyang.dts
arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts
arch/arm/boot/dts/aspeed-bmc-opp-swift.dts
arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts
arch/arm/boot/dts/aspeed-bmc-portwell-neptune.dts
arch/arm/boot/dts/aspeed-g4.dtsi
arch/arm/boot/dts/aspeed-g5.dtsi
arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
arch/arm/boot/dts/aspeed-g6.dtsi
arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-kizbox2-2.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-kizbox2-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-kizbox2.dts [deleted file]
arch/arm/boot/dts/at91-kizbox3-hs.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-kizbox3_common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
arch/arm/boot/dts/at91-sama5d2_xplained.dts
arch/arm/boot/dts/at91-sama5d4_xplained.dts
arch/arm/boot/dts/atlas7-evb.dts
arch/arm/boot/dts/bcm-cygnus.dtsi
arch/arm/boot/dts/bcm-hr2.dtsi
arch/arm/boot/dts/bcm2711-rpi-4-b.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm2711.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm2835-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm2835-rpi.dtsi
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/bcm2836.dtsi
arch/arm/boot/dts/bcm2837.dtsi
arch/arm/boot/dts/bcm283x-rpi-usb-peripheral.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm5301x.dtsi
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/dra7-l4.dtsi
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/e60k02.dtsi [new file with mode: 0644]
arch/arm/boot/dts/emev2.dtsi
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/boot/dts/exynos5.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5260.dtsi
arch/arm/boot/dts/exynos5410.dtsi
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5422-odroid-core.dtsi
arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
arch/arm/boot/dts/exynos54xx.dtsi
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/exynos5800.dtsi
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx31.dtsi
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53-qsb-common.dtsi
arch/arm/boot/dts/imx53-usbarmory.dts
arch/arm/boot/dts/imx6dl-apf6dev.dts
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
arch/arm/boot/dts/imx6dl-yapp4-hydra.dts
arch/arm/boot/dts/imx6dl.dtsi
arch/arm/boot/dts/imx6q-apalis-eval.dts
arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
arch/arm/boot/dts/imx6q-apalis-ixora.dts
arch/arm/boot/dts/imx6q-apf6dev.dts
arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
arch/arm/boot/dts/imx6q-dhcom-som.dtsi
arch/arm/boot/dts/imx6q-gw54xx.dts
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/imx6qdl-apalis.dtsi
arch/arm/boot/dts/imx6qdl-apf6.dtsi
arch/arm/boot/dts/imx6qdl-apf6dev.dtsi
arch/arm/boot/dts/imx6qdl-colibri.dtsi
arch/arm/boot/dts/imx6qdl-gw551x.dtsi
arch/arm/boot/dts/imx6qdl-rex.dtsi
arch/arm/boot/dts/imx6qdl-udoo.dtsi
arch/arm/boot/dts/imx6qdl-wandboard.dtsi
arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/imx6sll-kobo-clarahd.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6sll.dtsi
arch/arm/boot/dts/imx6sx.dtsi
arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-imx6ull-opos6uldev.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts
arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi
arch/arm/boot/dts/imx6ul-kontron-n6311-s.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-kontron-n6x1x-s.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-opos6ul.dtsi
arch/arm/boot/dts/imx6ul-opos6uldev.dts
arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi
arch/arm/boot/dts/imx6ul.dtsi
arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
arch/arm/boot/dts/imx6ull-colibri.dtsi
arch/arm/boot/dts/imx6ull-kontron-n6411-s.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-opos6ul.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-opos6uldev.dts [new file with mode: 0644]
arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
arch/arm/boot/dts/imx7-colibri.dtsi
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/imx7s.dtsi
arch/arm/boot/dts/imx7ulp-evk.dts
arch/arm/boot/dts/imx7ulp.dtsi
arch/arm/boot/dts/keystone-clocks.dtsi
arch/arm/boot/dts/keystone-k2e-clocks.dtsi
arch/arm/boot/dts/keystone-k2e-netcp.dtsi
arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
arch/arm/boot/dts/keystone-k2l-netcp.dtsi
arch/arm/boot/dts/kirkwood-synology.dtsi
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit-28.dts
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
arch/arm/boot/dts/logicpd-torpedo-som.dtsi
arch/arm/boot/dts/mmp3-dell-ariel.dts [new file with mode: 0644]
arch/arm/boot/dts/mmp3.dtsi [new file with mode: 0644]
arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi
arch/arm/boot/dts/motorola-mapphone-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/mt6323.dtsi
arch/arm/boot/dts/omap3-igep0020-rev-f.dts
arch/arm/boot/dts/omap3-igep0030-rev-g.dts
arch/arm/boot/dts/omap3-n900.dts
arch/arm/boot/dts/omap3-tao3530.dtsi
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi
arch/arm/boot/dts/omap4-droid-bionic-xt875.dts [new file with mode: 0644]
arch/arm/boot/dts/omap4-droid4-xt894.dts
arch/arm/boot/dts/omap4-l4-abe.dtsi
arch/arm/boot/dts/omap4-l4.dtsi
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/omap5-l4-abe.dtsi
arch/arm/boot/dts/omap5-l4.dtsi
arch/arm/boot/dts/omap5.dtsi
arch/arm/boot/dts/openbmc-flash-layout-128.dtsi [new file with mode: 0644]
arch/arm/boot/dts/qcom-ipq4019.dtsi
arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
arch/arm/boot/dts/qcom-msm8974.dtsi
arch/arm/boot/dts/qcom-pm8941.dtsi
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7793-gose.dts
arch/arm/boot/dts/rda8810pl.dtsi
arch/arm/boot/dts/rk3036.dtsi
arch/arm/boot/dts/rk3288-rock2-som.dtsi
arch/arm/boot/dts/rk3288-tinker.dtsi
arch/arm/boot/dts/rk3288-veyron-analog-audio.dtsi
arch/arm/boot/dts/rk3288-veyron-edp.dtsi
arch/arm/boot/dts/rk3288-veyron-jaq.dts
arch/arm/boot/dts/rk3288-veyron-mickey.dts
arch/arm/boot/dts/rk3288-veyron-minnie.dts
arch/arm/boot/dts/rk3288-veyron-tiger.dts
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/s3c6410-mini6410.dts
arch/arm/boot/dts/s3c6410-smdk6410.dts
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts
arch/arm/boot/dts/stm32429i-eval.dts
arch/arm/boot/dts/stm32746g-eval.dts
arch/arm/boot/dts/stm32f429-disco.dts
arch/arm/boot/dts/stm32f469-disco.dts
arch/arm/boot/dts/stm32f469.dtsi
arch/arm/boot/dts/stm32f746-disco.dts
arch/arm/boot/dts/stm32f769-disco.dts
arch/arm/boot/dts/stm32h743i-disco.dts
arch/arm/boot/dts/stm32h743i-eval.dts
arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
arch/arm/boot/dts/stm32mp157a-avenger96.dts
arch/arm/boot/dts/stm32mp157a-dk1.dts
arch/arm/boot/dts/stm32mp157c-dk2.dts
arch/arm/boot/dts/stm32mp157c-ed1.dts
arch/arm/boot/dts/stm32mp157c-ev1.dts
arch/arm/boot/dts/stm32mp157c.dtsi
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
arch/arm/boot/dts/sun8i-a83t.dtsi
arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-h3.dtsi
arch/arm/boot/dts/sun8i-r40.dtsi
arch/arm/boot/dts/sun9i-a80.dtsi
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
arch/arm/boot/dts/tegra124-venice2.dts
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra20-cpu-opp.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra20-paz00.dts
arch/arm/boot/dts/tegra20-trimslice.dts
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi
arch/arm/boot/dts/tegra30-apalis.dtsi
arch/arm/boot/dts/tegra30-cardhu-a04.dts
arch/arm/boot/dts/tegra30-colibri.dtsi
arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra30-cpu-opp.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/vf-colibri.dtsi
arch/arm/boot/dts/vf500-colibri.dtsi
arch/arm/boot/dts/vf610-bk4.dts
arch/arm/boot/dts/vf610-zii-scu4-aib.dts
arch/arm/configs/aspeed_g4_defconfig
arch/arm/configs/aspeed_g5_defconfig
arch/arm/configs/at91_dt_defconfig
arch/arm/configs/exynos_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/keystone_defconfig
arch/arm/configs/multi_v4t_defconfig
arch/arm/configs/multi_v5_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/qcom_defconfig
arch/arm/configs/sama5_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/configs/tegra_defconfig
arch/arm/crypto/curve25519-glue.c
arch/arm/include/asm/hardware/cache-l2x0.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/vdso/gettimeofday.h
arch/arm/kernel/smp.c
arch/arm/kernel/topology.c
arch/arm/mach-bcm/Kconfig
arch/arm/mach-bcm/Makefile
arch/arm/mach-bcm/bcm2711.c [new file with mode: 0644]
arch/arm/mach-bcm/bcm_kona_smc.c
arch/arm/mach-bcm/platsmp.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-hisi/Kconfig
arch/arm/mach-imx/anatop.c
arch/arm/mach-imx/cpu.c
arch/arm/mach-imx/hotplug.c
arch/arm/mach-mmp/Kconfig
arch/arm/mach-mmp/Makefile
arch/arm/mach-mmp/addr-map.h
arch/arm/mach-mmp/common.c
arch/arm/mach-mmp/common.h
arch/arm/mach-mmp/devices.c
arch/arm/mach-mmp/mmp-dt.c
arch/arm/mach-mmp/mmp2-dt.c
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-mmp/mmp3.c [new file with mode: 0644]
arch/arm/mach-mmp/platsmp.c [new file with mode: 0644]
arch/arm/mach-mmp/pm-mmp2.c
arch/arm/mach-mmp/pm-pxa910.c
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/pxa168.h
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-mmp/regs-usb.h
arch/arm/mach-mmp/time.c
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/ams-delta-fiq.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/control.c
arch/arm/mach-omap2/control.h
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/omap-mpuss-lowpower.c
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/omap_hwmod_43xx_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/omap_twl.c
arch/arm/mach-omap2/opp4xxx_data.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/pm44xx.c
arch/arm/mach-omap2/pmic-cpcap.c [new file with mode: 0644]
arch/arm/mach-omap2/prm44xx.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/vc.c
arch/arm/mach-omap2/vc.h
arch/arm/mach-pxa/icontrol.c
arch/arm/mach-s3c24xx/s3c2416.c
arch/arm/mach-s3c24xx/s3c2443.c
arch/arm/mach-s3c24xx/spi-core.h
arch/arm/mach-s3c64xx/setup-usb-phy.c
arch/arm/mach-shmobile/setup-rcar-gen2.c
arch/arm/mach-socfpga/socfpga.c
arch/arm/mach-tegra/reset-handler.S
arch/arm/mach-tegra/sleep-tegra30.S
arch/arm/mach-vexpress/spc.c
arch/arm/mm/Kconfig
arch/arm/mm/dma-mapping.c
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/include/plat/usb-phy.h
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
arch/arm64/boot/dts/actions/s900.dtsi
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h5-emlid-neutis-n5.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
arch/arm64/boot/dts/amlogic/Makefile
arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-a1.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-axg.dtsi
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
arch/arm64/boot/dts/amlogic/meson-g12.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
arch/arm64/boot/dts/amlogic/meson-gx.dtsi
arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
arch/arm64/boot/dts/amlogic/meson-gxm-vega-s96.dts
arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
arch/arm64/boot/dts/arm/juno-base.dtsi
arch/arm64/boot/dts/arm/juno-clocks.dtsi
arch/arm64/boot/dts/broadcom/Makefile
arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts [new file with mode: 0644]
arch/arm64/boot/dts/exynos/exynos5433.dtsi
arch/arm64/boot/dts/exynos/exynos7.dtsi
arch/arm64/boot/dts/freescale/Makefile
arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
arch/arm64/boot/dts/freescale/imx8mm-evk.dts
arch/arm64/boot/dts/freescale/imx8mm.dtsi
arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
arch/arm64/boot/dts/freescale/imx8mn-evk.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mn.dtsi
arch/arm64/boot/dts/freescale/imx8mq-evk.dts
arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts
arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts
arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
arch/arm64/boot/dts/freescale/imx8mq.dtsi
arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dts
arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
arch/arm64/boot/dts/freescale/imx8qxp.dtsi
arch/arm64/boot/dts/freescale/s32v234-evb.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/s32v234.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/hisilicon/hi6220.dtsi
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
arch/arm64/boot/dts/lg/lg1312.dtsi
arch/arm64/boot/dts/lg/lg1313.dtsi
arch/arm64/boot/dts/marvell/Makefile
arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
arch/arm64/boot/dts/marvell/armada-70x0.dtsi
arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi
arch/arm64/boot/dts/marvell/armada-80x0.dtsi
arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi
arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
arch/arm64/boot/dts/marvell/armada-ap806.dtsi
arch/arm64/boot/dts/marvell/armada-ap807-quad.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-ap807.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-ap80x.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-common.dtsi
arch/arm64/boot/dts/marvell/armada-cp110.dtsi
arch/arm64/boot/dts/marvell/armada-cp115.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-cp11x.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/cn9130-db.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/cn9130.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/cn9131-db.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/cn9132-db.dts [new file with mode: 0644]
arch/arm64/boot/dts/mediatek/mt8183.dtsi
arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
arch/arm64/boot/dts/nvidia/tegra186.dtsi
arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
arch/arm64/boot/dts/nvidia/tegra194.dtsi
arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts
arch/arm64/boot/dts/nvidia/tegra210.dtsi
arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
arch/arm64/boot/dts/qcom/msm8916.dtsi
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi
arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi
arch/arm64/boot/dts/qcom/msm8998-pins.dtsi
arch/arm64/boot/dts/qcom/msm8998.dtsi
arch/arm64/boot/dts/qcom/qcs404.dtsi
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
arch/arm64/boot/dts/qcom/sdm845-db845c.dts
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
arch/arm64/boot/dts/realtek/Makefile
arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts [new file with mode: 0644]
arch/arm64/boot/dts/realtek/rtd1293.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts
arch/arm64/boot/dts/realtek/rtd1295.dtsi
arch/arm64/boot/dts/realtek/rtd1296-ds418.dts [new file with mode: 0644]
arch/arm64/boot/dts/realtek/rtd1296.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/realtek/rtd129x.dtsi
arch/arm64/boot/dts/renesas/Makefile
arch/arm64/boot/dts/renesas/hihope-common.dtsi
arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi
arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m-ex.dts
arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m.dts
arch/arm64/boot/dts/renesas/r8a774a1.dtsi
arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex.dts [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n.dts [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a774b1.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a774c0.dtsi
arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
arch/arm64/boot/dts/renesas/r8a7795.dtsi
arch/arm64/boot/dts/renesas/r8a7796.dtsi
arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a77961.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a77965.dtsi
arch/arm64/boot/dts/renesas/r8a77970.dtsi
arch/arm64/boot/dts/renesas/r8a77980.dtsi
arch/arm64/boot/dts/renesas/r8a77990.dtsi
arch/arm64/boot/dts/renesas/r8a77995.dtsi
arch/arm64/boot/dts/renesas/rzg2-advantech-idk-1110wr-panel.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/Makefile
arch/arm64/boot/dts/rockchip/px30-evb.dts
arch/arm64/boot/dts/rockchip/px30.dtsi
arch/arm64/boot/dts/rockchip/rk3308-evb.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3308.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3328-a1.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts
arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/boot/dts/ti/k3-am65-main.dtsi
arch/arm64/boot/dts/ti/k3-am654-base-board.dts
arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
arch/arm64/boot/dts/ti/k3-j721e.dtsi
arch/arm64/boot/dts/xilinx/zynqmp.dtsi
arch/arm64/configs/defconfig
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/include/asm/sections.h
arch/arm64/include/asm/uaccess.h
arch/arm64/kernel/entry-ftrace.S
arch/arm64/kernel/entry.S
arch/arm64/kernel/insn.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/va_layout.c
arch/arm64/mm/dump.c
arch/arm64/mm/init.c
arch/c6x/include/asm/pgtable.h
arch/ia64/include/asm/agp.h
arch/ia64/include/asm/irqflags.h
arch/ia64/include/uapi/asm/gcc_intrin.h
arch/ia64/include/uapi/asm/intel_intrin.h
arch/ia64/include/uapi/asm/intrinsics.h
arch/m68k/coldfire/entry.S
arch/m68k/include/asm/mcf_pgalloc.h
arch/m68k/include/asm/mcf_pgtable.h
arch/m68k/include/asm/mmu_context.h
arch/m68k/include/asm/motorola_pgalloc.h
arch/m68k/include/asm/motorola_pgtable.h
arch/m68k/include/asm/page.h
arch/m68k/include/asm/pgtable_mm.h
arch/m68k/include/asm/pgtable_no.h
arch/m68k/include/asm/sun3_pgalloc.h
arch/m68k/include/asm/sun3_pgtable.h
arch/m68k/kernel/sys_m68k.c
arch/m68k/mm/init.c
arch/m68k/mm/kmap.c
arch/m68k/mm/mcfmmu.c
arch/m68k/mm/motorola.c
arch/m68k/sun3x/dvma.c
arch/microblaze/include/asm/page.h
arch/microblaze/include/asm/pgalloc.h
arch/microblaze/include/asm/pgtable.h
arch/microblaze/kernel/signal.c
arch/microblaze/mm/init.c
arch/microblaze/mm/pgtable.c
arch/mips/cavium-octeon/executive/cvmx-bootmem.c
arch/mips/include/uapi/asm/msgbuf.h
arch/mips/include/uapi/asm/sembuf.h
arch/nds32/include/asm/page.h
arch/nds32/include/asm/pgalloc.h
arch/nds32/include/asm/pgtable.h
arch/nds32/include/asm/tlb.h
arch/nds32/kernel/pm.c
arch/nds32/mm/fault.c
arch/nds32/mm/init.c
arch/nds32/mm/mm-nds32.c
arch/nds32/mm/proc.c
arch/nios2/mm/ioremap.c
arch/parisc/include/asm/page.h
arch/parisc/include/asm/pgalloc.h
arch/parisc/include/asm/pgtable.h
arch/parisc/include/asm/tlb.h
arch/parisc/include/uapi/asm/msgbuf.h
arch/parisc/include/uapi/asm/sembuf.h
arch/parisc/kernel/cache.c
arch/parisc/kernel/pci-dma.c
arch/parisc/mm/fixmap.c
arch/parisc/mm/hugetlbpage.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/archrandom.h
arch/powerpc/include/asm/bitops.h
arch/powerpc/include/asm/hvcall.h
arch/powerpc/include/asm/kvm_book3s_uvmem.h [new file with mode: 0644]
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/include/asm/ultravisor-api.h
arch/powerpc/include/asm/ultravisor.h
arch/powerpc/include/asm/vdso_datapage.h
arch/powerpc/include/uapi/asm/msgbuf.h
arch/powerpc/include/uapi/asm/sembuf.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/time.c
arch/powerpc/kernel/vdso32/gettimeofday.S
arch/powerpc/kernel/vdso64/gettimeofday.S
arch/powerpc/kvm/Makefile
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_uvmem.c [new file with mode: 0644]
arch/powerpc/kvm/powerpc.c
arch/powerpc/lib/pmem.c
arch/powerpc/mm/mem.c
arch/powerpc/net/bpf_jit32.h
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/platforms/powernv/opal-imc.c
arch/powerpc/sysdev/xive/spapr.c
arch/riscv/Kconfig.socs
arch/riscv/boot/Makefile
arch/riscv/configs/defconfig
arch/riscv/configs/rv32_defconfig
arch/riscv/mm/init.c
arch/s390/Kconfig
arch/s390/include/asm/bitops.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/uv.h
arch/s390/include/uapi/asm/ipcbuf.h
arch/s390/kernel/early.c
arch/s390/kernel/perf_cpum_sf.c
arch/s390/kernel/smp.c
arch/s390/lib/spinlock.c
arch/s390/lib/test_unwind.c
arch/s390/mm/kasan_init.c
arch/sh/drivers/platform_early.c
arch/sh/kernel/cpu/shmobile/cpuidle.c
arch/sh/kernel/kgdb.c
arch/sparc/include/asm/pgalloc_32.h
arch/sparc/include/asm/pgtable_32.h
arch/sparc/include/uapi/asm/ipcbuf.h
arch/sparc/include/uapi/asm/msgbuf.h
arch/sparc/include/uapi/asm/sembuf.h
arch/sparc/mm/fault_32.c
arch/sparc/mm/highmem.c
arch/sparc/mm/io-unit.c
arch/sparc/mm/iommu.c
arch/sparc/mm/srmmu.c
arch/sparc/net/bpf_jit_comp_32.c
arch/um/include/asm/pgtable-2level.h
arch/um/include/asm/pgtable-3level.h
arch/um/include/asm/pgtable.h
arch/um/kernel/mem.c
arch/um/kernel/skas/mmu.c
arch/um/kernel/skas/uaccess.c
arch/um/kernel/tlb.c
arch/um/kernel/trap.c
arch/x86/include/asm/bitops.h
arch/x86/include/uapi/asm/msgbuf.h
arch/x86/include/uapi/asm/sembuf.h
arch/x86/kernel/fpu/xstate.c
arch/x86/kernel/ftrace.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/vmx/vmx.h
arch/xtensa/include/uapi/asm/ipcbuf.h
arch/xtensa/include/uapi/asm/msgbuf.h
arch/xtensa/include/uapi/asm/sembuf.h
block/bfq-cgroup.c
block/bio-integrity.c
block/bio.c
block/blk-cgroup.c
block/blk-core.c
block/blk-zoned.c
block/blk.h
block/ioctl.c
crypto/adiantum.c
crypto/essiv.c
drivers/acpi/Kconfig
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/device_pm.c
drivers/acpi/ec.c
drivers/acpi/osl.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/android/binder.c
drivers/auxdisplay/charlcd.c
drivers/base/Kconfig
drivers/base/devtmpfs.c
drivers/base/node.c
drivers/base/platform.c
drivers/base/power/Makefile
drivers/base/power/qos-test.c [new file with mode: 0644]
drivers/base/power/qos.c
drivers/base/power/wakeup.c
drivers/block/brd.c
drivers/block/null_blk_main.c
drivers/block/rbd.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/bus/Kconfig
drivers/bus/hisi_lpc.c
drivers/bus/ti-sysc.c
drivers/char/agp/frontend.c
drivers/char/agp/generic.c
drivers/clk/Kconfig
drivers/clk/mmp/Makefile
drivers/clk/qcom/clk-rpmh.c
drivers/clk/qcom/gcc-qcs404.c
drivers/clk/qcom/gcc-sdm845.c
drivers/cpufreq/Kconfig.powerpc
drivers/cpufreq/Kconfig.x86
drivers/cpufreq/cpufreq-dt-platdev.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_performance.c
drivers/cpufreq/cpufreq_powersave.c
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/qcom-cpufreq-hw.c
drivers/cpufreq/tegra124-cpufreq.c
drivers/cpufreq/vexpress-spc-cpufreq.c
drivers/cpuidle/Kconfig
drivers/cpuidle/Kconfig.arm
drivers/cpuidle/cpuidle.c
drivers/cpuidle/driver.c
drivers/cpuidle/poll_state.c
drivers/devfreq/devfreq.c
drivers/dma-buf/sync_file.c
drivers/firmware/arm_scmi/bus.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/efi/efi.c
drivers/firmware/imx/imx-dsp.c
drivers/firmware/imx/imx-scu-irq.c
drivers/firmware/imx/imx-scu.c
drivers/firmware/meson/meson_sm.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/tegra/bpmp.c
drivers/firmware/xilinx/zynqmp.c
drivers/gpio/gpio-104-dio-48e.c
drivers/gpio/gpio-104-idi-48.c
drivers/gpio/gpio-74x164.c
drivers/gpio/gpio-gpio-mm.c
drivers/gpio/gpio-max3191x.c
drivers/gpio/gpio-pca953x.c
drivers/gpio/gpio-pci-idio-16.c
drivers/gpio/gpio-pcie-idio-24.c
drivers/gpio/gpio-pisosr.c
drivers/gpio/gpio-uniphier.c
drivers/gpio/gpio-ws16c48.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/amd/acp/Kconfig
drivers/gpu/drm/amd/amdgpu/Kconfig
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
drivers/gpu/drm/amd/amdgpu/cik.c
drivers/gpu/drm/amd/amdgpu/df_v3_6.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/vi.c
drivers/gpu/drm/amd/amdkfd/Kconfig
drivers/gpu/drm/amd/display/Kconfig
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
drivers/gpu/drm/amd/display/dc/dcn20/Makefile
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn21/Makefile
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
drivers/gpu/drm/amd/display/dc/dsc/Makefile
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
drivers/gpu/drm/amd/display/include/i2caux_interface.h
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
drivers/gpu/drm/amd/powerplay/inc/smu_v12_0.h
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
drivers/gpu/drm/amd/powerplay/renoir_ppt.c
drivers/gpu/drm/amd/powerplay/smu_internal.h
drivers/gpu/drm/amd/powerplay/smu_v11_0.c
drivers/gpu/drm/amd/powerplay/smu_v12_0.c
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_property.c
drivers/gpu/drm/i915/Kconfig.profile
drivers/gpu/drm/i915/display/intel_cdclk.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_fbc.c
drivers/gpu/drm/i915/display/intel_hdcp.c
drivers/gpu/drm/i915/display/intel_hdcp.h
drivers/gpu/drm/i915/display/intel_hdmi.c
drivers/gpu/drm/i915/gem/i915_gem_context.c
drivers/gpu/drm/i915/gt/intel_context.c
drivers/gpu/drm/i915/gt/intel_engine.h
drivers/gpu/drm/i915/gt/intel_engine_cs.c
drivers/gpu/drm/i915/gt/intel_engine_pm.c
drivers/gpu/drm/i915/gt/intel_engine_pm.h
drivers/gpu/drm/i915/gt/intel_engine_types.h
drivers/gpu/drm/i915/gt/intel_gt_pm.c
drivers/gpu/drm/i915/gt/intel_gt_pm.h
drivers/gpu/drm/i915/gt/intel_gt_requests.c
drivers/gpu/drm/i915/gt/intel_gt_requests.h
drivers/gpu/drm/i915/gt/intel_lrc.c
drivers/gpu/drm/i915/gt/intel_reset.c
drivers/gpu/drm/i915/gt/intel_ring.c
drivers/gpu/drm/i915/gt/intel_timeline.c
drivers/gpu/drm/i915/gt/intel_timeline_types.h
drivers/gpu/drm/i915/gt/selftest_engine_pm.c
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/i915_active.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_query.c
drivers/gpu/drm/i915/intel_wakeref.c
drivers/gpu/drm/i915/intel_wakeref.h
drivers/gpu/drm/mcde/mcde_dsi.c
drivers/gpu/drm/meson/meson_venc_cvbs.c
drivers/gpu/drm/mgag200/mgag200_drv.c
drivers/gpu/drm/mgag200/mgag200_drv.h
drivers/gpu/drm/mgag200/mgag200_main.c
drivers/gpu/drm/msm/Kconfig
drivers/gpu/drm/msm/adreno/a3xx_gpu.c
drivers/gpu/drm/msm/adreno/a3xx_gpu.h
drivers/gpu/drm/msm/adreno/a4xx_gpu.c
drivers/gpu/drm/msm/adreno/a4xx_gpu.h
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
drivers/gpu/drm/msm/adreno/a5xx_power.c
drivers/gpu/drm/msm/adreno/adreno_device.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/adreno/adreno_gpu.h
drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
drivers/gpu/drm/msm/dsi/dsi_cfg.c
drivers/gpu/drm/msm/dsi/dsi_cfg.h
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
drivers/gpu/drm/msm/hdmi/hdmi_phy.c
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_gpummu.c
drivers/gpu/drm/msm/msm_iommu.c
drivers/gpu/drm/msm/msm_mmu.h
drivers/gpu/drm/msm/msm_rd.c
drivers/gpu/drm/nouveau/dispnv50/atom.h
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/dispnv50/head.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.h
drivers/gpu/drm/omapdrm/omap_gem.c
drivers/gpu/drm/panfrost/panfrost_devfreq.c
drivers/gpu/drm/panfrost/panfrost_drv.c
drivers/gpu/drm/panfrost/panfrost_gem.c
drivers/gpu/drm/panfrost/panfrost_gem.h
drivers/gpu/drm/panfrost/panfrost_perfcnt.c
drivers/gpu/drm/panfrost/panfrost_perfcnt.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/gem.c
drivers/gpu/drm/tegra/hub.c
drivers/gpu/drm/tegra/plane.c
drivers/gpu/drm/tegra/sor.c
drivers/gpu/drm/tegra/vic.c
drivers/i2c/i2c-core-base.c
drivers/idle/intel_idle.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/ad7124.c
drivers/iio/adc/ad7606.c
drivers/iio/adc/ad7949.c
drivers/iio/adc/intel_mrfld_adc.c
drivers/iio/adc/max1027.c
drivers/iio/adc/max9611.c
drivers/iio/humidity/hdc100x.c
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
drivers/iio/temperature/ltc2983.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/counters.c
drivers/infiniband/core/ib_core_uverbs.c
drivers/infiniband/hw/efa/efa_verbs.c
drivers/infiniband/hw/hfi1/sdma.c
drivers/infiniband/hw/hfi1/verbs.h
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/cmd.c
drivers/infiniband/hw/mlx5/cmd.h
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/sw/rxe/rxe_net.c
drivers/infiniband/sw/rxe/rxe_recv.c
drivers/infiniband/sw/rxe/rxe_req.c
drivers/infiniband/sw/rxe/rxe_resp.c
drivers/infiniband/ulp/opa_vnic/opa_vnic_ethtool.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/snvs_pwrkey.c
drivers/input/misc/uinput.c
drivers/input/rmi4/rmi_f34v7.c
drivers/input/rmi4/rmi_smbus.c
drivers/input/touchscreen/goodix.c
drivers/interconnect/qcom/Kconfig
drivers/interconnect/qcom/msm8974.c
drivers/interconnect/qcom/qcs404.c
drivers/interconnect/qcom/sdm845.c
drivers/iommu/iommu.c
drivers/md/dm-clone-metadata.c
drivers/md/dm-clone-metadata.h
drivers/md/dm-clone-target.c
drivers/md/dm-mpath.c
drivers/md/dm-table.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin-metadata.h
drivers/md/dm-thin.c
drivers/md/dm-zoned-target.c
drivers/md/md.c
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/raid1.c
drivers/md/raid5-ppl.c
drivers/md/raid5.c
drivers/media/platform/omap3isp/isppreview.c
drivers/media/v4l2-core/v4l2-ioctl.c
drivers/memory/atmel-ebi.c
drivers/memory/brcmstb_dpfe.c
drivers/memory/emif.c
drivers/memory/jedec_ddr.h
drivers/memory/of_memory.c
drivers/memory/of_memory.h
drivers/memory/samsung/Kconfig
drivers/memory/samsung/Makefile
drivers/memory/samsung/exynos5422-dmc.c [new file with mode: 0644]
drivers/memory/tegra/Kconfig
drivers/memory/tegra/Makefile
drivers/memory/tegra/mc.c
drivers/memory/tegra/mc.h
drivers/memory/tegra/tegra114.c
drivers/memory/tegra/tegra124.c
drivers/memory/tegra/tegra20-emc.c
drivers/memory/tegra/tegra30-emc.c [new file with mode: 0644]
drivers/memory/tegra/tegra30.c
drivers/misc/sram-exec.c
drivers/net/can/slcan.c
drivers/net/can/usb/ucan.c
drivers/net/can/xilinx_can.c
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
drivers/net/ethernet/cavium/liquidio/octeon_console.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/emulex/benet/be_ethtool.c
drivers/net/ethernet/freescale/enetc/enetc.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
drivers/net/ethernet/intel/iavf/iavf_ethtool.c
drivers/net/ethernet/intel/ice/ice_ethtool.c
drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/igc/igc_ethtool.c
drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
drivers/net/ethernet/intel/ixgbevf/ethtool.c
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/port.c
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/netronome/nfp/bpf/jit.c
drivers/net/ethernet/netronome/nfp/bpf/main.c
drivers/net/ethernet/netronome/nfp/bpf/offload.c
drivers/net/ethernet/netronome/nfp/flower/main.h
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
drivers/net/ethernet/pensando/ionic/ionic_lif.c
drivers/net/ethernet/qlogic/qede/qede.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
drivers/net/ethernet/realtek/r8169_firmware.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/Kconfig
drivers/net/ethernet/ti/cpsw_ethtool.c
drivers/net/ethernet/ti/cpsw_priv.c
drivers/net/ethernet/ti/netcp_ethss.c
drivers/net/fjes/fjes_ethtool.c
drivers/net/geneve.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/phy/dp83867.c
drivers/net/phy/mdio-thunder.c
drivers/net/phy/sfp.c
drivers/net/ppp/ppp_generic.c
drivers/net/ppp/pppoe.c
drivers/net/usb/sierra_net.c
drivers/net/usb/usbnet.c
drivers/net/vxlan.c
drivers/net/wireless/marvell/libertas/debugfs.c
drivers/net/wireless/marvell/mwifiex/util.h
drivers/ntb/hw/amd/ntb_hw_amd.c
drivers/nvme/host/core.c
drivers/nvme/host/fc.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/nvme/host/rdma.c
drivers/nvme/target/fcloop.c
drivers/nvme/target/loop.c
drivers/nvmem/meson-efuse.c
drivers/of/platform.c
drivers/pci/controller/pcie-rockchip-host.c
drivers/phy/marvell/Kconfig
drivers/phy/marvell/Makefile
drivers/phy/marvell/phy-mmp3-usb.c [new file with mode: 0644]
drivers/power/avs/Kconfig
drivers/pwm/pwm-stm32.c
drivers/pwm/pwm-sun4i.c
drivers/rapidio/rio-access.c
drivers/rapidio/rio-driver.c
drivers/reset/Kconfig
drivers/reset/core.c
drivers/reset/hisilicon/reset-hi3660.c
drivers/reset/reset-brcmstb.c
drivers/reset/reset-meson-audio-arb.c
drivers/reset/reset-meson.c
drivers/reset/reset-uniphier-glue.c
drivers/reset/reset-zynqmp.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_core_mpc.h
drivers/s390/net/qeth_ethtool.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/be2iscsi/be_cmds.h
drivers/scsi/cxgbi/libcxgbi.c
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_discover.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_nvme.c
drivers/scsi/qla2xxx/qla_sup.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/scsi_transport_sas.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/scsi/sd_zbc.c
drivers/scsi/smartpqi/smartpqi_init.c
drivers/scsi/ufs/cdns-pltfrm.c
drivers/scsi/ufs/ufs_bsg.c
drivers/soc/amlogic/meson-gx-socinfo.c
drivers/soc/aspeed/aspeed-lpc-snoop.c
drivers/soc/atmel/Kconfig
drivers/soc/atmel/Makefile
drivers/soc/atmel/sfr.c [new file with mode: 0644]
drivers/soc/fsl/Kconfig
drivers/soc/fsl/Makefile
drivers/soc/fsl/rcpm.c [new file with mode: 0644]
drivers/soc/imx/soc-imx-scu.c
drivers/soc/imx/soc-imx8.c
drivers/soc/mediatek/mtk-cmdq-helper.c
drivers/soc/mediatek/mtk-scpsys.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/Makefile
drivers/soc/qcom/llcc-qcom.c [moved from drivers/soc/qcom/llcc-slice.c with 68% similarity]
drivers/soc/qcom/llcc-sdm845.c [deleted file]
drivers/soc/qcom/ocmem.c [new file with mode: 0644]
drivers/soc/qcom/qcom_aoss.c
drivers/soc/qcom/rpmpd.c
drivers/soc/qcom/smd-rpm.c
drivers/soc/qcom/socinfo.c
drivers/soc/renesas/Kconfig
drivers/soc/renesas/Makefile
drivers/soc/renesas/r8a7743-sysc.c
drivers/soc/renesas/r8a7745-sysc.c
drivers/soc/renesas/r8a77470-sysc.c
drivers/soc/renesas/r8a774a1-sysc.c
drivers/soc/renesas/r8a774b1-sysc.c [new file with mode: 0644]
drivers/soc/renesas/r8a774c0-sysc.c
drivers/soc/renesas/r8a7779-sysc.c
drivers/soc/renesas/r8a7790-sysc.c
drivers/soc/renesas/r8a7791-sysc.c
drivers/soc/renesas/r8a7792-sysc.c
drivers/soc/renesas/r8a7794-sysc.c
drivers/soc/renesas/r8a7795-sysc.c
drivers/soc/renesas/r8a7796-sysc.c
drivers/soc/renesas/r8a77965-sysc.c
drivers/soc/renesas/r8a77970-sysc.c
drivers/soc/renesas/r8a77980-sysc.c
drivers/soc/renesas/r8a77990-sysc.c
drivers/soc/renesas/r8a77995-sysc.c
drivers/soc/renesas/rcar-rst.c
drivers/soc/renesas/rcar-sysc.c
drivers/soc/renesas/rcar-sysc.h
drivers/soc/renesas/renesas-soc.c
drivers/soc/samsung/Kconfig
drivers/soc/samsung/Makefile
drivers/soc/samsung/exynos-asv.c [new file with mode: 0644]
drivers/soc/samsung/exynos-asv.h [new file with mode: 0644]
drivers/soc/samsung/exynos-chipid.c
drivers/soc/samsung/exynos5422-asv.c [new file with mode: 0644]
drivers/soc/samsung/exynos5422-asv.h [new file with mode: 0644]
drivers/soc/tegra/Kconfig
drivers/soc/tegra/Makefile
drivers/soc/tegra/flowctrl.c
drivers/soc/tegra/fuse/fuse-tegra.c
drivers/soc/tegra/fuse/fuse-tegra30.c
drivers/soc/tegra/fuse/fuse.h
drivers/soc/tegra/pmc.c
drivers/soc/tegra/regulators-tegra20.c [new file with mode: 0644]
drivers/soc/tegra/regulators-tegra30.c [new file with mode: 0644]
drivers/soc/ti/Makefile
drivers/soc/ti/omap_prm.c [new file with mode: 0644]
drivers/soc/xilinx/zynqmp_pm_domains.c
drivers/staging/exfat/exfat.h
drivers/staging/exfat/exfat_core.c
drivers/staging/exfat/exfat_super.c
drivers/staging/fbtft/fb_uc1611.c
drivers/staging/fbtft/fb_watterott.c
drivers/staging/fbtft/fbtft-core.c
drivers/staging/hp/Kconfig
drivers/staging/isdn/gigaset/usb-gigaset.c
drivers/staging/octeon/Kconfig
drivers/staging/qlge/qlge_ethtool.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/rtl8712/usb_intf.c
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
drivers/staging/wfx/data_tx.c
drivers/staging/wlan-ng/Kconfig
drivers/target/iscsi/cxgbit/cxgbit_main.c
drivers/tee/optee/call.c
drivers/tee/optee/core.c
drivers/tee/optee/shm_pool.c
drivers/thermal/Kconfig
drivers/thermal/Makefile
drivers/thermal/amlogic_thermal.c [new file with mode: 0644]
drivers/thermal/cpu_cooling.c
drivers/thermal/intel/intel_soc_dts_iosf.c
drivers/thermal/intel/intel_soc_dts_iosf.h
drivers/thermal/qcom/tsens-8960.c
drivers/thermal/qcom/tsens-common.c
drivers/thermal/qcom/tsens-v0_1.c
drivers/thermal/qcom/tsens-v1.c
drivers/thermal/qcom/tsens-v2.c
drivers/thermal/qcom/tsens.c
drivers/thermal/qcom/tsens.h
drivers/thermal/qoriq_thermal.c
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/thermal-generic-adc.c
drivers/thermal/thermal_core.c
drivers/thermal/thermal_mmio.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/atm/usbatm.c
drivers/usb/common/usb-conn-gpio.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/urb.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_ecm.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_rndis.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/adutux.c
drivers/usb/misc/idmouse.c
drivers/usb/mon/mon_bin.c
drivers/usb/roles/class.c
drivers/usb/serial/io_edgeport.c
drivers/usb/storage/scsiglue.c
drivers/usb/typec/class.c
drivers/vfio/pci/vfio_pci_intrs.c
drivers/vfio/vfio_iommu_type1.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/vhost/vsock.c
drivers/virtio/virtio_balloon.c
drivers/xen/balloon.c
drivers/xen/events/events_base.c
drivers/xen/gntdev-common.h
drivers/xen/gntdev-dmabuf.c
drivers/xen/gntdev.c
drivers/xen/xenbus/xenbus_probe.c
fs/afs/dynroot.c
fs/afs/mntpt.c
fs/afs/proc.c
fs/afs/server.c
fs/afs/super.c
fs/autofs/autofs_i.h
fs/autofs/expire.c
fs/autofs/root.c
fs/binfmt_elf.c
fs/block_dev.c
fs/btrfs/Kconfig
fs/ceph/cache.c
fs/ceph/cache.h
fs/ceph/caps.c
fs/ceph/debugfs.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/mdsmap.c
fs/ceph/super.c
fs/ceph/super.h
fs/cifs/cifsacl.c
fs/cifs/cifsacl.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/sess.c
fs/cifs/smb2inode.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smb2proto.h
fs/crypto/keyring.c
fs/dcache.c
fs/debugfs/inode.c
fs/erofs/xattr.c
fs/eventpoll.c
fs/ext4/inode-test.c
fs/fcntl.c
fs/file.c
fs/fuse/Kconfig
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/readdir.c
fs/fuse/virtio_fs.c
fs/gfs2/aops.c
fs/gfs2/bmap.c
fs/gfs2/file.c
fs/gfs2/glock.c
fs/gfs2/glops.c
fs/gfs2/inode.c
fs/gfs2/log.c
fs/gfs2/log.h
fs/gfs2/lops.c
fs/gfs2/lops.h
fs/gfs2/meta_io.c
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/recovery.c
fs/gfs2/super.c
fs/gfs2/sys.c
fs/gfs2/trans.c
fs/gfs2/util.c
fs/gfs2/util.h
fs/internal.h
fs/io-wq.c
fs/io-wq.h
fs/io_uring.c
fs/iomap/buffered-io.c
fs/kernfs/mount.c
fs/lockd/host.c
fs/namei.c
fs/namespace.c
fs/nfs/callback.h
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/delegation.c
fs/nfs/delegation.h
fs/nfs/export.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/namespace.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3client.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs42.h
fs/nfs/nfs42proc.c
fs/nfs/nfs42xdr.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4file.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4super.c
fs/nfs/nfs4trace.h
fs/nfs/nfs4xdr.c
fs/nfs/nfstrace.h
fs/nfs/pnfs.c
fs/nfs/super.c
fs/nfs/sysfs.c
fs/nfsd/Kconfig
fs/nfsd/filecache.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsd.h
fs/nfsd/nfssvc.c
fs/nfsd/state.h
fs/nfsd/vfs.c
fs/nfsd/vfs.h
fs/orangefs/file.c
fs/orangefs/inode.c
fs/orangefs/orangefs-kernel.h
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/export.c
fs/overlayfs/inode.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/ovl_entry.h
fs/overlayfs/super.c
fs/pipe.c
fs/proc/Kconfig
fs/proc/generic.c
fs/proc/internal.h
fs/quota/dquot.c
fs/splice.c
fs/verity/enable.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/xfs_log.c
include/asm-generic/4level-fixup.h [deleted file]
include/asm-generic/bitops-instrumented.h [deleted file]
include/asm-generic/bitops/find.h
include/asm-generic/bitops/instrumented-atomic.h [new file with mode: 0644]
include/asm-generic/bitops/instrumented-lock.h [new file with mode: 0644]
include/asm-generic/bitops/instrumented-non-atomic.h [new file with mode: 0644]
include/dt-bindings/pinctrl/rockchip.h
include/dt-bindings/power/qcom-rpmpd.h
include/dt-bindings/reset/amlogic,meson-a1-reset.h [new file with mode: 0644]
include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h
include/dt-bindings/reset/realtek,rtd1295.h [new file with mode: 0644]
include/linux/agpgart.h
include/linux/bitmap.h
include/linux/bitops.h
include/linux/blk-cgroup.h
include/linux/blkdev.h
include/linux/build_bug.h
include/linux/bvec.h
include/linux/ceph/libceph.h
include/linux/cpu_cooling.h
include/linux/cpuidle.h
include/linux/dcache.h
include/linux/devfreq.h
include/linux/device.h
include/linux/energy_model.h
include/linux/export.h
include/linux/filter.h
include/linux/firmware/meson/meson_sm.h
include/linux/firmware/xlnx-zynqmp.h
include/linux/ftrace.h
include/linux/genalloc.h
include/linux/i2c.h
include/linux/initrd.h
include/linux/kcov.h
include/linux/kernel.h
include/linux/kvm_host.h
include/linux/lockd/debug.h
include/linux/lockd/lockd.h
include/linux/logic_pio.h
include/linux/mfd/stm32-timers.h
include/linux/mfd/syscon/atmel-matrix.h
include/linux/miscdevice.h
include/linux/mm.h
include/linux/moduleparam.h
include/linux/namei.h
include/linux/netdevice.h
include/linux/nfs4.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h
include/linux/notifier.h
include/linux/nvme-fc-driver.h
include/linux/phy_led_triggers.h
include/linux/pipe_fs_i.h
include/linux/platform_data/ti-prm.h [new file with mode: 0644]
include/linux/platform_data/ti-sysc.h
include/linux/pm_qos.h
include/linux/pm_wakeup.h
include/linux/printk.h
include/linux/proc_fs.h
include/linux/pwm.h
include/linux/qcom_scm.h
include/linux/rbtree_augmented.h
include/linux/reset-controller.h
include/linux/reset.h
include/linux/sched.h
include/linux/skbuff.h
include/linux/soc/mmp/cputype.h [moved from arch/arm/mach-mmp/cputype.h with 70% similarity]
include/linux/soc/qcom/llcc-qcom.h
include/linux/socket.h
include/linux/sunrpc/auth.h
include/linux/sunrpc/auth_gss.h
include/linux/sunrpc/clnt.h
include/linux/sunrpc/gss_api.h
include/linux/sunrpc/gss_err.h
include/linux/sunrpc/msg_prot.h
include/linux/sunrpc/rpc_pipe_fs.h
include/linux/sunrpc/svcauth.h
include/linux/sunrpc/svcauth_gss.h
include/linux/sunrpc/xdr.h
include/linux/sunrpc/xprt.h
include/linux/sunrpc/xprtsock.h
include/linux/syscalls.h
include/linux/sysctl.h
include/linux/thermal.h
include/linux/thread_info.h
include/linux/time.h
include/linux/vmstat.h
include/net/flow_dissector.h
include/net/flow_offload.h
include/net/garp.h
include/net/ip.h
include/net/ip_tunnels.h
include/net/ipv6.h
include/net/ipv6_stubs.h
include/net/mrp.h
include/net/netfilter/nf_conntrack_helper.h
include/net/netfilter/nf_tables_core.h
include/net/sock.h
include/net/tcp.h
include/rdma/ib_verbs.h
include/soc/qcom/ocmem.h [new file with mode: 0644]
include/soc/tegra/mc.h
include/sound/hdaudio.h
include/trace/events/rpcgss.h
include/trace/events/rpcrdma.h
include/trace/events/sunrpc.h
include/trace/trace_events.h
include/uapi/asm-generic/ipcbuf.h
include/uapi/asm-generic/msgbuf.h
include/uapi/asm-generic/sembuf.h
include/uapi/linux/input-event-codes.h
include/uapi/linux/io_uring.h
include/uapi/linux/kcov.h
include/uapi/linux/kvm.h
include/uapi/linux/scc.h
init/Kconfig
init/do_mounts.c
init/do_mounts_initrd.c
init/main.c
ipc/util.c
kernel/bpf/btf.c
kernel/bpf/cgroup.c
kernel/bpf/local_storage.c
kernel/bpf/verifier.c
kernel/dma/remap.c
kernel/kcov.c
kernel/module.c
kernel/notifier.c
kernel/power/qos.c
kernel/profile.c
kernel/sched/cpufreq_schedutil.c
kernel/sys.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/fgraph.c
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_events.c
kernel/trace/trace_events_inject.c [new file with mode: 0644]
kernel/workqueue.c
lib/Kconfig
lib/Kconfig.debug
lib/Kconfig.kgdb
lib/Makefile
lib/bitmap.c
lib/find_bit.c
lib/genalloc.c
lib/logic_pio.c
lib/math/rational.c
lib/raid6/unroll.awk
lib/test_bitmap.c
lib/test_meminit.c
lib/ubsan.c
mm/kasan/common.c
mm/ksm.c
mm/memcontrol.c
mm/memory.c
mm/slab_common.c
mm/vmstat.c
net/802/mrp.c
net/batman-adv/main.c
net/bpf/test_run.c
net/bridge/br.c
net/bridge/br_device.c
net/ceph/ceph_common.c
net/ceph/messenger.c
net/ceph/mon_client.c
net/core/dev.c
net/core/filter.c
net/core/flow_dissector.c
net/core/flow_offload.c
net/core/lwt_bpf.c
net/core/net-sysfs.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/xdp.c
net/dccp/ipv6.c
net/dccp/proto.c
net/hsr/hsr_device.c
net/ipv4/devinet.c
net/ipv4/gre_demux.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv4/ip_vti.c
net/ipv4/tcp.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv6/addrconf_core.c
net/ipv6/af_inet6.c
net/ipv6/datagram.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_output.c
net/ipv6/raw.c
net/ipv6/syncookies.c
net/ipv6/tcp_ipv6.c
net/iucv/af_iucv.c
net/l2tp/l2tp_ip6.c
net/mpls/af_mpls.c
net/netfilter/nf_tables_api.c
net/netfilter/nf_tables_offload.c
net/netfilter/nfnetlink_cthelper.c
net/netfilter/nft_ct.c
net/netfilter/nft_masq.c
net/netfilter/nft_nat.c
net/netfilter/nft_redir.c
net/netfilter/nft_tproxy.c
net/netfilter/xt_RATEEST.c
net/netlink/af_netlink.c
net/nfc/nci/spi.c
net/openvswitch/actions.c
net/openvswitch/conntrack.c
net/openvswitch/datapath.c
net/openvswitch/flow.h
net/rxrpc/af_rxrpc.c
net/sched/act_ct.c
net/sched/act_mpls.c
net/sched/cls_api.c
net/sched/cls_flower.c
net/sched/sch_cake.c
net/sched/sch_mq.c
net/sched/sch_mqprio.c
net/sctp/ipv6.c
net/socket.c
net/sunrpc/auth_gss/gss_mech_switch.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c
net/sunrpc/sched.c
net/sunrpc/svc.c
net/sunrpc/svcauth.c
net/sunrpc/xdr.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/backchannel.c
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtrdma/xprt_rdma.h
net/sunrpc/xprtsock.c
net/tipc/core.c
net/tipc/udp_media.c
net/tls/tls_device.c
net/tls/tls_main.c
net/tls/tls_sw.c
net/unix/af_unix.c
samples/bpf/xdp_rxq_info_user.c
scripts/checkpatch.pl
scripts/get_maintainer.pl
scripts/link-vmlinux.sh
security/integrity/ima/ima_policy.c
sound/core/oss/linear.c
sound/core/oss/mulaw.c
sound/core/oss/route.c
sound/drivers/aloop.c
sound/firewire/fireface/ff-pcm.c
sound/firewire/motu/motu-pcm.c
sound/firewire/oxfw/oxfw-pcm.c
sound/hda/hdac_stream.c
sound/pci/echoaudio/echoaudio_dsp.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/hdmi-codec.c
tools/lib/bpf/.gitignore
tools/lib/bpf/Makefile
tools/lib/bpf/libbpf.c
tools/perf/MANIFEST
tools/testing/kunit/kunit_tool_test.py
tools/testing/selftests/Makefile
tools/testing/selftests/bpf/.gitignore
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
tools/testing/selftests/bpf/progs/fentry_test.c
tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c
tools/testing/selftests/bpf/progs/fexit_bpf2bpf_simple.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/fexit_test.c
tools/testing/selftests/bpf/progs/test_mmap.c
tools/testing/selftests/bpf/progs/test_pkt_md_access.c
tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c
tools/testing/selftests/bpf/test_cpp.cpp [moved from tools/lib/bpf/test_libbpf.c with 100% similarity]
tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
tools/testing/selftests/bpf/test_tcpbpf.h
tools/testing/selftests/bpf/test_tcpbpf_user.c
tools/testing/selftests/filesystems/epoll/.gitignore [new file with mode: 0644]
tools/testing/selftests/filesystems/epoll/Makefile [new file with mode: 0644]
tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c [new file with mode: 0644]
tools/testing/selftests/ftrace/test.d/ftrace/func-filter-stacktrace.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_cpumask.tc
tools/testing/selftests/ftrace/test.d/functions
tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-action-hist-xfail.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onchange-action-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-snapshot-action-hist.tc
tools/testing/selftests/kselftest/module.sh
tools/testing/selftests/kselftest/prefix.pl
tools/testing/selftests/kselftest/runner.sh
tools/testing/selftests/net/tls.c
tools/testing/selftests/safesetid/Makefile
tools/testing/selftests/safesetid/safesetid-test.c
usr/include/Makefile

index 89c411b..4b32eaa 100644 (file)
@@ -1,2 +1,4 @@
 *.c   diff=cpp
 *.h   diff=cpp
+*.dtsi diff=dts
+*.dts  diff=dts
index 1fd03c7..b37212c 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -105,6 +105,9 @@ James E Wilson <wilson@specifix.com>
 James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
 James Hogan <jhogan@kernel.org> <james@albanarts.com>
 James Ketrenos <jketreno@io.(none)>
+Jan Glauber <jan.glauber@gmail.com> <jang@de.ibm.com>
+Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com>
+Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com>
 Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>
 Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
 Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
@@ -149,6 +152,7 @@ Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
 Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
 Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
 Li Yang <leoyang.li@nxp.com> <leoli@freescale.com>
+Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
 Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
 Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com>
 Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
@@ -273,3 +277,5 @@ Gustavo Padovan <gustavo@las.ic.unicamp.br>
 Gustavo Padovan <padovan@profusion.mobi>
 Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
 Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
+Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
+Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
index 594095b..c00f9f1 100644 (file)
@@ -144,7 +144,7 @@ journal_crypt:algorithm(:key)       (the key is optional)
        Encrypt the journal using given algorithm to make sure that the
        attacker can't read the journal. You can use a block cipher here
        (such as "cbc(aes)") or a stream cipher (for example "chacha20",
-       "salsa20", "ctr(aes)" or "ecb(arc4)").
+       "salsa20" or "ctr(aes)").
 
        The journal contains history of last writes to the block device,
        an attacker reading the journal could see the last sector nubmers
index 4872fb6..ec62fcc 100644 (file)
@@ -8,6 +8,7 @@ Device Mapper
     cache-policies
     cache
     delay
+    dm-clone
     dm-crypt
     dm-dust
     dm-flakey
index 5a92d89..ade4e6e 100644 (file)
                        the GPE dispatcher.
                        This facility can be used to prevent such uncontrolled
                        GPE floodings.
-                       Format: <int>
+                       Format: <byte>
 
        acpi_no_auto_serialize  [HW,ACPI]
                        Disable auto-serialization of AML methods
index c9a44c9..1adf53d 100644 (file)
@@ -103,7 +103,7 @@ the Microchip website: http://www.microchip.com.
 
           * Datasheet
 
-          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet_B.pdf
 
     * ARM Cortex-A5 + NEON based SoCs
       - sama5d4 family
@@ -167,7 +167,7 @@ the Microchip website: http://www.microchip.com.
 
           * Datasheet
 
-          http://ww1.microchip.com/downloads/en/DeviceDoc/60001527A.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/SAM-E70-S70-V70-V71-Family-Data-Sheet-DS60001527D.pdf
 
 
 Linux kernel information
index 098a46f..a5af2cb 100644 (file)
@@ -129,7 +129,7 @@ writing of special-purpose memory allocators in the future.
    :functions: gen_pool_for_each_chunk
 
 .. kernel-doc:: lib/genalloc.c
-   :functions: addr_in_gen_pool
+   :functions: gen_pool_has_addr
 
 .. kernel-doc:: lib/genalloc.c
    :functions: gen_pool_avail
index f77de49..4ac53a1 100644 (file)
@@ -57,7 +57,13 @@ The Linux kernel provides more basic utility functions.
 Bit Operations
 --------------
 
-.. kernel-doc:: include/asm-generic/bitops-instrumented.h
+.. kernel-doc:: include/asm-generic/bitops/instrumented-atomic.h
+   :internal:
+
+.. kernel-doc:: include/asm-generic/bitops/instrumented-non-atomic.h
+   :internal:
+
+.. kernel-doc:: include/asm-generic/bitops/instrumented-lock.h
    :internal:
 
 Bitmap Operations
index 42b6126..36890b0 100644 (file)
@@ -34,6 +34,7 @@ Profiling data will only become accessible once debugfs has been mounted::
 
 Coverage collection
 -------------------
+
 The following program demonstrates coverage collection from within a test
 program using kcov:
 
@@ -128,6 +129,7 @@ only need to enable coverage (disable happens automatically on thread end).
 
 Comparison operands collection
 ------------------------------
+
 Comparison operands collection is similar to coverage collection:
 
 .. code-block:: c
@@ -202,3 +204,130 @@ Comparison operands collection is similar to coverage collection:
 
 Note that the kcov modes (coverage collection or comparison operands) are
 mutually exclusive.
+
+Remote coverage collection
+--------------------------
+
+With KCOV_ENABLE coverage is collected only for syscalls that are issued
+from the current process. With KCOV_REMOTE_ENABLE it's possible to collect
+coverage for arbitrary parts of the kernel code, provided that those parts
+are annotated with kcov_remote_start()/kcov_remote_stop().
+
+This allows to collect coverage from two types of kernel background
+threads: the global ones, that are spawned during kernel boot in a limited
+number of instances (e.g. one USB hub_event() worker thread is spawned per
+USB HCD); and the local ones, that are spawned when a user interacts with
+some kernel interface (e.g. vhost workers).
+
+To enable collecting coverage from a global background thread, a unique
+global handle must be assigned and passed to the corresponding
+kcov_remote_start() call. Then a userspace process can pass a list of such
+handles to the KCOV_REMOTE_ENABLE ioctl in the handles array field of the
+kcov_remote_arg struct. This will attach the used kcov device to the code
+sections, that are referenced by those handles.
+
+Since there might be many local background threads spawned from different
+userspace processes, we can't use a single global handle per annotation.
+Instead, the userspace process passes a non-zero handle through the
+common_handle field of the kcov_remote_arg struct. This common handle gets
+saved to the kcov_handle field in the current task_struct and needs to be
+passed to the newly spawned threads via custom annotations. Those threads
+should in turn be annotated with kcov_remote_start()/kcov_remote_stop().
+
+Internally kcov stores handles as u64 integers. The top byte of a handle
+is used to denote the id of a subsystem that this handle belongs to, and
+the lower 4 bytes are used to denote the id of a thread instance within
+that subsystem. A reserved value 0 is used as a subsystem id for common
+handles as they don't belong to a particular subsystem. The bytes 4-7 are
+currently reserved and must be zero. In the future the number of bytes
+used for the subsystem or handle ids might be increased.
+
+When a particular userspace proccess collects coverage by via a common
+handle, kcov will collect coverage for each code section that is annotated
+to use the common handle obtained as kcov_handle from the current
+task_struct. However non common handles allow to collect coverage
+selectively from different subsystems.
+
+.. code-block:: c
+
+    struct kcov_remote_arg {
+       unsigned        trace_mode;
+       unsigned        area_size;
+       unsigned        num_handles;
+       uint64_t        common_handle;
+       uint64_t        handles[0];
+    };
+
+    #define KCOV_INIT_TRACE                    _IOR('c', 1, unsigned long)
+    #define KCOV_DISABLE                       _IO('c', 101)
+    #define KCOV_REMOTE_ENABLE         _IOW('c', 102, struct kcov_remote_arg)
+
+    #define COVER_SIZE (64 << 10)
+
+    #define KCOV_TRACE_PC      0
+
+    #define KCOV_SUBSYSTEM_COMMON      (0x00ull << 56)
+    #define KCOV_SUBSYSTEM_USB (0x01ull << 56)
+
+    #define KCOV_SUBSYSTEM_MASK        (0xffull << 56)
+    #define KCOV_INSTANCE_MASK (0xffffffffull)
+
+    static inline __u64 kcov_remote_handle(__u64 subsys, __u64 inst)
+    {
+       if (subsys & ~KCOV_SUBSYSTEM_MASK || inst & ~KCOV_INSTANCE_MASK)
+               return 0;
+       return subsys | inst;
+    }
+
+    #define KCOV_COMMON_ID     0x42
+    #define KCOV_USB_BUS_NUM   1
+
+    int main(int argc, char **argv)
+    {
+       int fd;
+       unsigned long *cover, n, i;
+       struct kcov_remote_arg *arg;
+
+       fd = open("/sys/kernel/debug/kcov", O_RDWR);
+       if (fd == -1)
+               perror("open"), exit(1);
+       if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
+               perror("ioctl"), exit(1);
+       cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
+                                    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       if ((void*)cover == MAP_FAILED)
+               perror("mmap"), exit(1);
+
+       /* Enable coverage collection via common handle and from USB bus #1. */
+       arg = calloc(1, sizeof(*arg) + sizeof(uint64_t));
+       if (!arg)
+               perror("calloc"), exit(1);
+       arg->trace_mode = KCOV_TRACE_PC;
+       arg->area_size = COVER_SIZE;
+       arg->num_handles = 1;
+       arg->common_handle = kcov_remote_handle(KCOV_SUBSYSTEM_COMMON,
+                                                       KCOV_COMMON_ID);
+       arg->handles[0] = kcov_remote_handle(KCOV_SUBSYSTEM_USB,
+                                               KCOV_USB_BUS_NUM);
+       if (ioctl(fd, KCOV_REMOTE_ENABLE, arg))
+               perror("ioctl"), free(arg), exit(1);
+       free(arg);
+
+       /*
+        * Here the user needs to trigger execution of a kernel code section
+        * that is either annotated with the common handle, or to trigger some
+        * activity on USB bus #1.
+        */
+       sleep(2);
+
+       n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
+       for (i = 0; i < n; i++)
+               printf("0x%lx\n", cover[i + 1]);
+       if (ioctl(fd, KCOV_DISABLE, 0))
+               perror("ioctl"), exit(1);
+       if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
+               perror("munmap"), exit(1);
+       if (close(fd))
+               perror("close"), exit(1);
+       return 0;
+    }
index ecdfdc9..61ae13c 100644 (file)
@@ -203,12 +203,12 @@ Test Module
 Kselftest tests the kernel from userspace.  Sometimes things need
 testing from within the kernel, one method of doing this is to create a
 test module.  We can tie the module into the kselftest framework by
-using a shell script test runner.  ``kselftest_module.sh`` is designed
+using a shell script test runner.  ``kselftest/module.sh`` is designed
 to facilitate this process.  There is also a header file provided to
 assist writing kernel modules that are for use with kselftest:
 
 - ``tools/testing/kselftest/kselftest_module.h``
-- ``tools/testing/kselftest/kselftest_module.sh``
+- ``tools/testing/kselftest/kselftest/module.sh``
 
 How to use
 ----------
@@ -247,7 +247,7 @@ A bare bones test module might look like this:
 
    #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-   #include "../tools/testing/selftests/kselftest_module.h"
+   #include "../tools/testing/selftests/kselftest/module.h"
 
    KSTM_MODULE_GLOBALS();
 
@@ -276,7 +276,7 @@ Example test script
 
     #!/bin/bash
     # SPDX-License-Identifier: GPL-2.0+
-    $(dirname $0)/../kselftest_module.sh "foo" test_foo
+    $(dirname $0)/../kselftest/module.sh "foo" test_foo
 
 
 Test Harness
index 26ffb46..c60d760 100644 (file)
@@ -9,6 +9,7 @@ KUnit - Unit Testing for the Linux Kernel
 
        start
        usage
+       kunit-tool
        api/index
        faq
 
diff --git a/Documentation/dev-tools/kunit/kunit-tool.rst b/Documentation/dev-tools/kunit/kunit-tool.rst
new file mode 100644 (file)
index 0000000..50d4639
--- /dev/null
@@ -0,0 +1,57 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+kunit_tool How-To
+=================
+
+What is kunit_tool?
+===================
+
+kunit_tool is a script (``tools/testing/kunit/kunit.py``) that aids in building
+the Linux kernel as UML (`User Mode Linux
+<http://user-mode-linux.sourceforge.net/>`_), running KUnit tests, parsing
+the test results and displaying them in a user friendly manner.
+
+What is a kunitconfig?
+======================
+
+It's just a defconfig that kunit_tool looks for in the base directory.
+kunit_tool uses it to generate a .config as you might expect. In addition, it
+verifies that the generated .config contains the CONFIG options in the
+kunitconfig; the reason it does this is so that it is easy to be sure that a
+CONFIG that enables a test actually ends up in the .config.
+
+How do I use kunit_tool?
+========================
+
+If a kunitconfig is present at the root directory, all you have to do is:
+
+.. code-block:: bash
+
+       ./tools/testing/kunit/kunit.py run
+
+However, you most likely want to use it with the following options:
+
+.. code-block:: bash
+
+       ./tools/testing/kunit/kunit.py run --timeout=30 --jobs=`nproc --all`
+
+- ``--timeout`` sets a maximum amount of time to allow tests to run.
+- ``--jobs`` sets the number of threads to use to build the kernel.
+
+If you just want to use the defconfig that ships with the kernel, you can
+append the ``--defconfig`` flag as well:
+
+.. code-block:: bash
+
+       ./tools/testing/kunit/kunit.py run --timeout=30 --jobs=`nproc --all` --defconfig
+
+.. note::
+       This command is particularly helpful for getting started because it
+       just works. No kunitconfig needs to be present.
+
+For a list of all the flags supported by kunit_tool, you can run:
+
+.. code-block:: bash
+
+       ./tools/testing/kunit/kunit.py run --help
index aeeddfa..9d6db89 100644 (file)
@@ -19,11 +19,14 @@ The wrapper can be run with:
 
 .. code-block:: bash
 
-   ./tools/testing/kunit/kunit.py run
+       ./tools/testing/kunit/kunit.py run --defconfig
+
+For more information on this wrapper (also called kunit_tool) checkout the
+:doc:`kunit-tool` page.
 
 Creating a kunitconfig
 ======================
-The Python script is a thin wrapper around Kbuild as such, it needs to be
+The Python script is a thin wrapper around Kbuild. As such, it needs to be
 configured with a ``kunitconfig`` file. This file essentially contains the
 regular Kernel config, with the specific test targets as well.
 
@@ -59,8 +62,8 @@ If everything worked correctly, you should see the following:
 followed by a list of tests that are run. All of them should be passing.
 
 .. note::
-   Because it is building a lot of sources for the first time, the ``Building
-   kunit kernel`` step may take a while.
+       Because it is building a lot of sources for the first time, the
+       ``Building KUnit kernel`` step may take a while.
 
 Writing your first test
 =======================
@@ -159,7 +162,7 @@ Now you can run the test:
 
 .. code-block:: bash
 
-       ./tools/testing/kunit/kunit.py
+       ./tools/testing/kunit/kunit.py run
 
 You should see the following failure:
 
index c6e6963..b9a065a 100644 (file)
@@ -16,7 +16,7 @@ Organization of this document
 =============================
 
 This document is organized into two main sections: Testing and Isolating
-Behavior. The first covers what a unit test is and how to use KUnit to write
+Behavior. The first covers what unit tests are and how to use KUnit to write
 them. The second covers how to use KUnit to isolate code and make it possible
 to unit test code that was otherwise un-unit-testable.
 
@@ -174,13 +174,13 @@ Test Suites
 ~~~~~~~~~~~
 
 Now obviously one unit test isn't very helpful; the power comes from having
-many test cases covering all of your behaviors. Consequently it is common to
-have many *similar* tests; in order to reduce duplication in these closely
-related tests most unit testing frameworks provide the concept of a *test
-suite*, in KUnit we call it a *test suite*; all it is is just a collection of
-test cases for a unit of code with a set up function that gets invoked before
-every test cases and then a tear down function that gets invoked after every
-test case completes.
+many test cases covering all of a unit's behaviors. Consequently it is common
+to have many *similar* tests; in order to reduce duplication in these closely
+related tests most unit testing frameworks - including KUnit - provide the
+concept of a *test suite*. A *test suite* is just a collection of test cases
+for a unit of code with a set up function that gets invoked before every test
+case and then a tear down function that gets invoked after every test case
+completes.
 
 Example:
 
@@ -211,7 +211,7 @@ KUnit test framework.
 .. note::
    A test case will only be run if it is associated with a test suite.
 
-For more information on these types of things see the :doc:`api/test`.
+For more information on these types of things see the :doc:`api/test`.
 
 Isolating Behavior
 ==================
@@ -338,7 +338,7 @@ We can easily test this code by *faking out* the underlying EEPROM:
                return count;
        }
 
-       ssize_t fake_eeprom_write(struct eeprom *this, size_t offset, const char *buffer, size_t count)
+       ssize_t fake_eeprom_write(struct eeprom *parent, size_t offset, const char *buffer, size_t count)
        {
                struct fake_eeprom *this = container_of(parent, struct fake_eeprom, parent);
 
@@ -454,7 +454,7 @@ KUnit on non-UML architectures
 By default KUnit uses UML as a way to provide dependencies for code under test.
 Under most circumstances KUnit's usage of UML should be treated as an
 implementation detail of how KUnit works under the hood. Nevertheless, there
-are instances where being able to run architecture specific code, or test
+are instances where being able to run architecture specific code or test
 against real hardware is desirable. For these reasons KUnit supports running on
 other architectures.
 
@@ -557,7 +557,7 @@ run your tests on your hardware setup just by compiling for your architecture.
 .. important::
    Always prefer tests that run on UML to tests that only run under a particular
    architecture, and always prefer tests that run under QEMU or another easy
-   (and monitarily free) to obtain software environment to a specific piece of
+   (and monetarily free) to obtain software environment to a specific piece of
    hardware.
 
 Nevertheless, there are still valid reasons to write an architecture or hardware
index 99015ce..c6a4433 100644 (file)
@@ -94,7 +94,7 @@ properties:
               - amlogic,p212
               - hwacom,amazetv
               - khadas,vim
-              - libretech,cc
+              - libretech,aml-s905x-cc
               - nexbox,a95x
           - const: amlogic,s905x
           - const: amlogic,meson-gxl
@@ -147,6 +147,7 @@ properties:
           - enum:
               - hardkernel,odroid-n2
               - khadas,vim3
+              - ugoos,am6
           - const: amlogic,s922x
           - const: amlogic,g12b
 
@@ -156,4 +157,10 @@ properties:
               - seirobotics,sei610
               - khadas,vim3l
           - const: amlogic,sm1
+
+      - description: Boards with the Amlogic Meson A1 A113L SoC
+        items:
+          - enum:
+              - amlogic,ad401
+          - const: amlogic,a1
 ...
index 6e168ab..6dd8be4 100644 (file)
@@ -45,6 +45,13 @@ properties:
           - const: atmel,at91sam9x5
           - const: atmel,at91sam9
 
+      - description: Overkiz kizbox3 board
+        items:
+          - const: overkiz,kizbox3-hs
+          - const: atmel,sama5d27
+          - const: atmel,sama5d2
+          - const: atmel,sama5
+
       - items:
           - const: atmel,sama5d27
           - const: atmel,sama5d2
@@ -73,6 +80,13 @@ properties:
           - const: atmel,sama5d3
           - const: atmel,sama5
 
+      - description: Overkiz kizbox2 board with two heads
+        items:
+          - const: overkiz,kizbox2-2
+          - const: atmel,sama5d31
+          - const: atmel,sama5d3
+          - const: atmel,sama5
+
       - items:
           - enum:
               - atmel,sama5d31
diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
new file mode 100644 (file)
index 0000000..dd52e29
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/bcm/bcm2835.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM2711/BCM2835 Platforms Device Tree Bindings
+
+maintainers:
+  - Eric Anholt <eric@anholt.net>
+  - Stefan Wahren <wahrenst@gmx.net>
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+      - description: BCM2711 based Boards
+        items:
+          - enum:
+              - raspberrypi,4-model-b
+          - const: brcm,bcm2711
+
+      - description: BCM2835 based Boards
+        items:
+          - enum:
+              - raspberrypi,model-a
+              - raspberrypi,model-a-plus
+              - raspberrypi,model-b
+              - raspberrypi,model-b-i2c0  # Raspberry Pi Model B (no P5)
+              - raspberrypi,model-b-rev2
+              - raspberrypi,model-b-plus
+              - raspberrypi,compute-module
+              - raspberrypi,model-zero
+              - raspberrypi,model-zero-w
+          - const: brcm,bcm2835
+
+      - description: BCM2836 based Boards
+        items:
+          - enum:
+              - raspberrypi,2-model-b
+          - const: brcm,bcm2836
+
+      - description: BCM2837 based Boards
+        items:
+          - enum:
+              - raspberrypi,3-model-a-plus
+              - raspberrypi,3-model-b
+              - raspberrypi,3-model-b-plus
+              - raspberrypi,3-compute-module
+              - raspberrypi,3-compute-module-lite
+          - const: brcm,bcm2837
+
+...
diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
deleted file mode 100644 (file)
index 245328f..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-Broadcom BCM2835 device tree bindings
--------------------------------------------
-
-Raspberry Pi Model A
-Required root node properties:
-compatible = "raspberrypi,model-a", "brcm,bcm2835";
-
-Raspberry Pi Model A+
-Required root node properties:
-compatible = "raspberrypi,model-a-plus", "brcm,bcm2835";
-
-Raspberry Pi Model B
-Required root node properties:
-compatible = "raspberrypi,model-b", "brcm,bcm2835";
-
-Raspberry Pi Model B (no P5)
-early model B with I2C0 rather than I2C1 routed to the expansion header
-Required root node properties:
-compatible = "raspberrypi,model-b-i2c0", "brcm,bcm2835";
-
-Raspberry Pi Model B rev2
-Required root node properties:
-compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835";
-
-Raspberry Pi Model B+
-Required root node properties:
-compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
-
-Raspberry Pi 2 Model B
-Required root node properties:
-compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
-
-Raspberry Pi 3 Model A+
-Required root node properties:
-compatible = "raspberrypi,3-model-a-plus", "brcm,bcm2837";
-
-Raspberry Pi 3 Model B
-Required root node properties:
-compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
-
-Raspberry Pi 3 Model B+
-Required root node properties:
-compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837";
-
-Raspberry Pi Compute Module
-Required root node properties:
-compatible = "raspberrypi,compute-module", "brcm,bcm2835";
-
-Raspberry Pi Compute Module 3
-Required root node properties:
-compatible = "raspberrypi,3-compute-module", "brcm,bcm2837";
-
-Raspberry Pi Compute Module 3 Lite
-Required root node properties:
-compatible = "raspberrypi,3-compute-module-lite", "brcm,bcm2837";
-
-Raspberry Pi Zero
-Required root node properties:
-compatible = "raspberrypi,model-zero", "brcm,bcm2835";
-
-Raspberry Pi Zero W
-Required root node properties:
-compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
-
-Generic BCM2835 board
-Required root node properties:
-compatible = "brcm,bcm2835";
index cb30895..c23c24f 100644 (file)
@@ -189,6 +189,7 @@ properties:
               - marvell,armada-390-smp
               - marvell,armada-xp-smp
               - marvell,98dx3236-smp
+              - marvell,mmp3-smp
               - mediatek,mt6589-smp
               - mediatek,mt81xx-tz-smp
               - qcom,gcc-msm8660
index 1b4b4e6..f79683a 100644 (file)
@@ -38,12 +38,16 @@ properties:
       - description: i.MX27 Product Development Kit
         items:
           - enum:
+              - armadeus,imx27-apf27      # APF27 SoM
+              - armadeus,imx27-apf27dev   # APF27 SoM on APF27Dev board
               - fsl,imx27-pdk
           - const: fsl,imx27
 
       - description: i.MX28 based Boards
         items:
           - enum:
+              - armadeus,imx28-apf28      # APF28 SoM
+              - armadeus,imx28-apf28dev   # APF28 SoM on APF28Dev board
               - fsl,imx28-evk
               - i2se,duckbill
               - i2se,duckbill-2
@@ -87,7 +91,8 @@ properties:
       - description: i.MX51 Babbage Board
         items:
           - enum:
-              - armadeus,imx51-apf51
+              - armadeus,imx51-apf51    # APF51 SoM
+              - armadeus,imx51-apf51dev # APF51 SoM on APF51Dev board
               - fsl,imx51-babbage
               - technologic,imx51-ts4800
           - const: fsl,imx51
@@ -106,6 +111,8 @@ properties:
       - description: i.MX6Q based Boards
         items:
           - enum:
+              - armadeus,imx6q-apf6       # APF6 (Quad/Dual) SoM
+              - armadeus,imx6q-apf6dev    # APF6 (Quad/Dual) SoM on APF6Dev board
               - emtrion,emcon-mx6         # emCON-MX6D or emCON-MX6Q SoM
               - emtrion,emcon-mx6-avari   # emCON-MX6D or emCON-MX6Q SoM on Avari Base
               - fsl,imx6q-arm2
@@ -114,6 +121,11 @@ properties:
               - fsl,imx6q-sabresd
               - technologic,imx6q-ts4900
               - technologic,imx6q-ts7970
+              - toradex,apalis_imx6q            # Apalis iMX6 Module
+              - toradex,apalis_imx6q-eval       # Apalis iMX6 Module on Apalis Evaluation Board
+              - toradex,apalis_imx6q-ixora      # Apalis iMX6 Module on Ixora
+              - toradex,apalis_imx6q-ixora-v1.1 # Apalis iMX6 Module on Ixora V1.1
+              - variscite,dt6customboard
           - const: fsl,imx6q
 
       - description: i.MX6QP based Boards
@@ -126,6 +138,8 @@ properties:
       - description: i.MX6DL based Boards
         items:
           - enum:
+              - armadeus,imx6dl-apf6      # APF6 (Solo) SoM
+              - armadeus,imx6dl-apf6dldev # APF6 (Solo) SoM on APF6Dev board
               - eckelmann,imx6dl-ci4x10
               - emtrion,emcon-mx6         # emCON-MX6S or emCON-MX6DL SoM
               - emtrion,emcon-mx6-avari   # emCON-MX6S or emCON-MX6DL SoM on Avari Base
@@ -133,6 +147,8 @@ properties:
               - fsl,imx6dl-sabresd        # i.MX6 DualLite SABRE Smart Device Board
               - technologic,imx6dl-ts4900
               - technologic,imx6dl-ts7970
+              - toradex,colibri_imx6dl          # Colibri iMX6 Module
+              - toradex,colibri_imx6dl-eval-v3  # Colibri iMX6 Module on Colibri Evaluation Board V3
               - ysoft,imx6dl-yapp4-draco  # i.MX6 DualLite Y Soft IOTA Draco board
               - ysoft,imx6dl-yapp4-hydra  # i.MX6 DualLite Y Soft IOTA Hydra board
               - ysoft,imx6dl-yapp4-ursa   # i.MX6 Solo Y Soft IOTA Ursa board
@@ -148,6 +164,7 @@ properties:
         items:
           - enum:
               - fsl,imx6sll-evk
+              - kobo,clarahd
           - const: fsl,imx6sll
 
       - description: i.MX6SX based Boards
@@ -160,8 +177,11 @@ properties:
       - description: i.MX6UL based Boards
         items:
           - enum:
+              - armadeus,imx6ul-opos6ul    # OPOS6UL (i.MX6UL) SoM
+              - armadeus,imx6ul-opos6uldev # OPOS6UL (i.MX6UL) SoM on OPOS6ULDev board
               - fsl,imx6ul-14x14-evk      # i.MX6 UltraLite 14x14 EVK Board
               - kontron,imx6ul-n6310-som  # Kontron N6310 SOM
+              - kontron,imx6ul-n6311-som  # Kontron N6311 SOM
           - const: fsl,imx6ul
 
       - description: Kontron N6310 S Board
@@ -170,6 +190,12 @@ properties:
           - const: kontron,imx6ul-n6310-som
           - const: fsl,imx6ul
 
+      - description: Kontron N6311 S Board
+        items:
+          - const: kontron,imx6ul-n6311-s
+          - const: kontron,imx6ul-n6311-som
+          - const: fsl,imx6ul
+
       - description: Kontron N6310 S 43 Board
         items:
           - const: kontron,imx6ul-n6310-s-43
@@ -180,7 +206,18 @@ properties:
       - description: i.MX6ULL based Boards
         items:
           - enum:
+              - armadeus,imx6ull-opos6ul    # OPOS6UL (i.MX6ULL) SoM
+              - armadeus,imx6ull-opos6uldev # OPOS6UL (i.MX6ULL) SoM on OPOS6ULDev board
               - fsl,imx6ull-14x14-evk     # i.MX6 UltraLiteLite 14x14 EVK Board
+              - kontron,imx6ull-n6411-som # Kontron N6411 SOM
+              - toradex,colibri-imx6ull-eval            # Colibri iMX6ULL Module on Colibri Evaluation Board
+              - toradex,colibri-imx6ull-wifi-eval       # Colibri iMX6ULL Wi-Fi / Bluetooth Module on Colibri Evaluation Board
+          - const: fsl,imx6ull
+
+      - description: Kontron N6411 S Board
+        items:
+          - const: kontron,imx6ull-n6411-s
+          - const: kontron,imx6ull-n6411-som
           - const: fsl,imx6ull
 
       - description: i.MX6ULZ based Boards
@@ -193,6 +230,8 @@ properties:
       - description: i.MX7S based Boards
         items:
           - enum:
+              - toradex,colibri-imx7s           # Colibri iMX7 Solo Module
+              - toradex,colibri-imx7s-eval-v3   # Colibri iMX7 Solo Module on Colibri Evaluation Board V3
               - tq,imx7s-mba7             # i.MX7S TQ MBa7 with TQMa7S SoM
           - const: fsl,imx7s
 
@@ -201,6 +240,10 @@ properties:
           - enum:
               - fsl,imx7d-sdb             # i.MX7 SabreSD Board
               - novtech,imx7d-meerkat96   # i.MX7 Meerkat96 Board
+              - toradex,colibri-imx7d                   # Colibri iMX7 Dual Module
+              - toradex,colibri-imx7d-emmc              # Colibri iMX7 Dual 1GB (eMMC) Module
+              - toradex,colibri-imx7d-emmc-eval-v3      # Colibri iMX7 Dual 1GB (eMMC) Module on Colibri Evaluation Board V3
+              - toradex,colibri-imx7d-eval-v3           # Colibri iMX7 Dual Module on Colibri Evaluation Board V3
               - tq,imx7d-mba7             # i.MX7D TQ MBa7 with TQMa7D SoM
               - zii,imx7d-rmu2            # ZII RMU2 Board
               - zii,imx7d-rpu2            # ZII RPU2 Board
@@ -233,6 +276,7 @@ properties:
         items:
           - enum:
               - fsl,imx8mn-ddr4-evk       # i.MX8MN DDR4 EVK Board
+              - fsl,imx8mn-evk            # i.MX8MN LPDDR4 EVK Board
           - const: fsl,imx8mn
 
       - description: i.MX8MQ based Boards
@@ -250,6 +294,8 @@ properties:
           - enum:
               - einfochips,imx8qxp-ai_ml  # i.MX8QXP AI_ML Board
               - fsl,imx8qxp-mek           # i.MX8QXP MEK Board
+              - toradex,colibri-imx8x         # Colibri iMX8X Module
+              - toradex,colibri-imx8x-eval-v3 # Colibri iMX8X Module on Colibri Evaluation Board V3
           - const: fsl,imx8qxp
 
       - description:
@@ -267,6 +313,10 @@ properties:
               - fsl,vf600
               - fsl,vf610
               - fsl,vf610m4
+              - toradex,vf500-colibri_vf50              # Colibri VF50 Module
+              - toradex,vf500-colibri_vf50-on-eval      # Colibri VF50 Module on Colibri Evaluation Board
+              - toradex,vf610-colibri_vf61              # Colibri VF61 Module
+              - toradex,vf610-colibri_vf61-on-eval      # Colibri VF61 Module on Colibri Evaluation Board
 
       - description: ZII's VF610 based Boards
         items:
@@ -335,4 +385,10 @@ properties:
               - fsl,ls2088a-rdb
           - const: fsl,ls2088a
 
+      - description: S32V234 based Boards
+        items:
+          - enum:
+              - fsl,s32v234-evb           # S32V234-EVB2 Customer Evaluation Board
+          - const: fsl,s32v234
+
 ...
@@ -1,15 +1,15 @@
-Marvell Armada AP806 System Controller
+Marvell Armada AP80x System Controller
 ======================================
 
-The AP806 is one of the two core HW blocks of the Marvell Armada 7K/8K
-SoCs. It contains system controllers, which provide several registers
-giving access to numerous features: clocks, pin-muxing and many other
-SoC configuration items. This DT binding allows to describe these
-system controllers.
+The AP806/AP807 is one of the two core HW blocks of the Marvell Armada
+7K/8K/931x SoCs. It contains system controllers, which provide several
+registers giving access to numerous features: clocks, pin-muxing and
+many other SoC configuration items. This DT binding allows to describe
+these system controllers.
 
 For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
- - reg: register area of the AP806 system controller
+ - reg: register area of the AP80x system controller
 
 SYSTEM CONTROLLER 0
 ===================
diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.txt b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.txt
deleted file mode 100644 (file)
index df98a9c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-Marvell Armada 7K/8K Platforms Device Tree Bindings
----------------------------------------------------
-
-Boards using a SoC of the Marvell Armada 7K or 8K families must carry
-the following root node property:
-
- - compatible, with one of the following values:
-
-   - "marvell,armada7020", "marvell,armada-ap806-dual", "marvell,armada-ap806"
-      when the SoC being used is the Armada 7020
-
-   - "marvell,armada7040", "marvell,armada-ap806-quad", "marvell,armada-ap806"
-      when the SoC being used is the Armada 7040
-
-   - "marvell,armada8020", "marvell,armada-ap806-dual", "marvell,armada-ap806"
-      when the SoC being used is the Armada 8020
-
-   - "marvell,armada8040", "marvell,armada-ap806-quad", "marvell,armada-ap806"
-      when the SoC being used is the Armada 8040
-
-Example:
-
-compatible = "marvell,armada7040-db", "marvell,armada7040",
-             "marvell,armada-ap806-quad", "marvell,armada-ap806";
diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml
new file mode 100644 (file)
index 0000000..a9828c5
--- /dev/null
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR X11)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/marvell/armada-7k-8k.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell Armada 7K/8K Platforms Device Tree Bindings
+
+maintainers:
+  - Gregory CLEMENT <gregory.clement@bootlin.com>
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+
+      - description: Armada 7020 SoC
+        items:
+          - const: marvell,armada7020
+          - const: marvell,armada-ap806-dual
+          - const: marvell,armada-ap806
+
+      - description: Armada 7040 SoC
+        items:
+          - const: marvell,armada7040
+          - const: marvell,armada-ap806-quad
+          - const: marvell,armada-ap806
+
+      - description: Armada 8020 SoC
+        items:
+          - const: marvell,armada8020
+          - const: marvell,armada-ap806-dual
+          - const: marvell,armada-ap806
+
+      - description: Armada 8040 SoC
+        items:
+          - const: marvell,armada8040
+          - const: marvell,armada-ap806-quad
+          - const: marvell,armada-ap806
+
+      - description: Armada CN9130 SoC with no external CP
+        items:
+          - const: marvell,cn9130
+          - const: marvell,armada-ap807-quad
+          - const: marvell,armada-ap807
+
+      - description: Armada CN9131 SoC with one external CP
+        items:
+          - const: marvell,cn9131
+          - const: marvell,cn9130
+          - const: marvell,armada-ap807-quad
+          - const: marvell,armada-ap807
+
+      - description: Armada CN9132 SoC with two external CPs
+        items:
+          - const: marvell,cn9132
+          - const: marvell,cn9131
+          - const: marvell,cn9130
+          - const: marvell,armada-ap807-quad
+          - const: marvell,armada-ap807
diff --git a/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt
deleted file mode 100644 (file)
index 9516875..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-Marvell Platforms Device Tree Bindings
-----------------------------------------------------
-
-PXA168 Aspenite Board
-Required root node properties:
-       - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168";
-
-PXA910 DKB Board
-Required root node properties:
-       - compatible = "mrvl,pxa910-dkb";
-
-MMP2 Brownstone Board
-Required root node properties:
-       - compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2";
diff --git a/Documentation/devicetree/bindings/arm/mrvl/mrvl.yaml b/Documentation/devicetree/bindings/arm/mrvl/mrvl.yaml
new file mode 100644 (file)
index 0000000..818dfe6
--- /dev/null
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/mrvl/mrvl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell Platforms Device Tree Bindings
+
+maintainers:
+  - Lubomir Rintel <lkundrak@v3.sk>
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+      - description: PXA168 Aspenite Board
+        items:
+          - enum:
+              - mrvl,pxa168-aspenite
+          - const: mrvl,pxa168
+      - description: PXA910 DKB Board
+        items:
+          - enum:
+              - mrvl,pxa910-dkb
+          - const: mrvl,pxa910
+      - description: MMP2 based boards
+        items:
+          - enum:
+              - mrvl,mmp2-brownstone
+          - const: mrvl,mmp2
+      - description: MMP3 based boards
+        items:
+          - const: mrvl,mmp3
+...
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
deleted file mode 100644 (file)
index eaee06b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-== Introduction==
-
-LLCC (Last Level Cache Controller) provides last level of cache memory in SOC,
-that can be shared by multiple clients. Clients here are different cores in the
-SOC, the idea is to minimize the local caches at the clients and migrate to
-common pool of memory. Cache memory is divided into partitions called slices
-which are assigned to clients. Clients can query the slice details, activate
-and deactivate them.
-
-Properties:
-- compatible:
-       Usage: required
-       Value type: <string>
-       Definition: must be "qcom,sdm845-llcc"
-
-- reg:
-       Usage: required
-       Value Type: <prop-encoded-array>
-       Definition: The first element specifies the llcc base start address and
-                   the size of the register region. The second element specifies
-                   the llcc broadcast base address and size of the register region.
-
-- reg-names:
-        Usage: required
-        Value Type: <stringlist>
-        Definition: Register region names. Must be "llcc_base", "llcc_broadcast_base".
-
-- interrupts:
-       Usage: required
-       Definition: The interrupt is associated with the llcc edac device.
-                       It's used for llcc cache single and double bit error detection
-                       and reporting.
-
-Example:
-
-       cache-controller@1100000 {
-               compatible = "qcom,sdm845-llcc";
-               reg = <0x1100000 0x200000>, <0x1300000 0x50000> ;
-               reg-names = "llcc_base", "llcc_broadcast_base";
-               interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
-       };
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
new file mode 100644 (file)
index 0000000..5587490
--- /dev/null
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/msm/qcom,llcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Last Level Cache Controller
+
+maintainers:
+  - Rishabh Bhatnagar <rishabhb@codeaurora.org>
+  - Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
+
+description: |
+  LLCC (Last Level Cache Controller) provides last level of cache memory in SoC,
+  that can be shared by multiple clients. Clients here are different cores in the
+  SoC, the idea is to minimize the local caches at the clients and migrate to
+  common pool of memory. Cache memory is divided into partitions called slices
+  which are assigned to clients. Clients can query the slice details, activate
+  and deactivate them.
+
+properties:
+  compatible:
+    enum:
+      - qcom,sc7180-llcc
+      - qcom,sdm845-llcc
+
+  reg:
+    items:
+      - description: LLCC base register region
+      - description: LLCC broadcast base register region
+
+  reg-names:
+    items:
+      - const: llcc_base
+      - const: llcc_broadcast_base
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    cache-controller@1100000 {
+      compatible = "qcom,sdm845-llcc";
+      reg = <0x1100000 0x200000>, <0x1300000 0x50000> ;
+      reg-names = "llcc_base", "llcc_broadcast_base";
+      interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
+    };
diff --git a/Documentation/devicetree/bindings/arm/omap/prm-inst.txt b/Documentation/devicetree/bindings/arm/omap/prm-inst.txt
new file mode 100644 (file)
index 0000000..fcd3456
--- /dev/null
@@ -0,0 +1,29 @@
+OMAP PRM instance bindings
+
+Power and Reset Manager is an IP block on OMAP family of devices which
+handle the power domains and their current state, and provide reset
+handling for the domains and/or separate IP blocks under the power domain
+hierarchy.
+
+Required properties:
+- compatible:  Must contain one of the following:
+               "ti,am3-prm-inst"
+               "ti,am4-prm-inst"
+               "ti,omap4-prm-inst"
+               "ti,omap5-prm-inst"
+               "ti,dra7-prm-inst"
+               and additionally must contain:
+               "ti,omap-prm-inst"
+- reg:         Contains PRM instance register address range
+               (base address and length)
+
+Optional properties:
+- #reset-cells:        Should be 1 if the PRM instance in question supports resets.
+
+Example:
+
+prm_dsp2: prm@1b00 {
+       compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+       reg = <0x1b00 0x40>;
+       #reset-cells = <1>;
+};
index 3528b61..ab59de1 100644 (file)
@@ -13,11 +13,24 @@ properties:
   $nodename:
     const: '/'
   compatible:
-    # RTD1295 SoC based boards
-    items:
-      - enum:
-          - mele,v9
-          - probox2,ava
-          - zidoo,x9s
-      - const: realtek,rtd1295
+    oneOf:
+      # RTD1293 SoC based boards
+      - items:
+          - enum:
+              - synology,ds418j # Synology DiskStation DS418j
+          - const: realtek,rtd1293
+
+      # RTD1295 SoC based boards
+      - items:
+          - enum:
+              - mele,v9 # MeLE V9
+              - probox2,ava # ProBox2 AVA
+              - zidoo,x9s # Zidoo X9S
+          - const: realtek,rtd1295
+
+      # RTD1296 SoC based boards
+      - items:
+          - enum:
+              - synology,ds418 # Synology DiskStation DS418
+          - const: realtek,rtd1296
 ...
diff --git a/Documentation/devicetree/bindings/arm/renesas,prr.txt b/Documentation/devicetree/bindings/arm/renesas,prr.txt
deleted file mode 100644 (file)
index 08e482e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Renesas Product Register
-
-Most Renesas ARM SoCs have a Product Register or Boundary Scan ID Register that
-allows to retrieve SoC product and revision information.  If present, a device
-node for this register should be added.
-
-Required properties:
-  - compatible: Must be one of:
-    "renesas,prr"
-    "renesas,bsid"
-  - reg: Base address and length of the register block.
-
-
-Examples
---------
-
-       prr: chipid@ff000044 {
-               compatible = "renesas,prr";
-               reg = <0 0xff000044 0 4>;
-       };
diff --git a/Documentation/devicetree/bindings/arm/renesas,prr.yaml b/Documentation/devicetree/bindings/arm/renesas,prr.yaml
new file mode 100644 (file)
index 0000000..7f8d17f
--- /dev/null
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/renesas,prr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas Product Register
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+  - Magnus Damm <magnus.damm@gmail.com>
+
+description: |
+  Most Renesas ARM SoCs have a Product Register or Boundary Scan ID
+  Register that allows to retrieve SoC product and revision information.
+  If present, a device node for this register should be added.
+
+properties:
+  compatible:
+    enum:
+      - renesas,prr
+      - renesas,bsid
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    prr: chipid@ff000044 {
+        compatible = "renesas,prr";
+        reg = <0 0xff000044 0 4>;
+    };
index 28eb458..9436124 100644 (file)
@@ -116,6 +116,18 @@ properties:
           - const: hoperun,hihope-rzg2m
           - const: renesas,r8a774a1
 
+      - description: RZ/G2N (R8A774B1)
+        items:
+          - enum:
+              - hoperun,hihope-rzg2n # HopeRun HiHope RZ/G2N platform
+          - const: renesas,r8a774b1
+
+      - items:
+          - enum:
+              - hoperun,hihope-rzg2-ex # HopeRun expansion board for HiHope RZ/G2 platforms
+          - const: hoperun,hihope-rzg2n
+          - const: renesas,r8a774b1
+
       - description: RZ/G2E (R8A774C0)
         items:
           - enum:
@@ -193,15 +205,23 @@ properties:
               - renesas,salvator-xs # Salvator-XS (Salvator-X 2nd version, RTP0RC7796SIPB0012S)
           - const: renesas,r8a7796
 
+      - description: R-Car M3-W+ (R8A77961)
+        items:
+          - enum:
+              - renesas,salvator-xs # Salvator-XS (Salvator-X 2nd version, RTP0RC7796SIPB0012SA5A)
+          - const: renesas,r8a77961
+
       - description: Kingfisher (SBEV-RCAR-KF-M03)
         items:
           - const: shimafuji,kingfisher
           - enum:
               - renesas,h3ulcb
               - renesas,m3ulcb
+              - renesas,m3nulcb
           - enum:
               - renesas,r8a7795
               - renesas,r8a7796
+              - renesas,r8a77965
 
       - description: R-Car M3-N (R8A77965)
         items:
index 9c7e703..d9847b3 100644 (file)
@@ -40,6 +40,11 @@ properties:
           - const: asus,rk3288-tinker-s
           - const: rockchip,rk3288
 
+      - description: Beelink A1
+        items:
+          - const: azw,beelink-a1
+          - const: rockchip,rk3328
+
       - description: bq Curie 2 tablet
         items:
           - const: mundoreader,bq-curie2
@@ -82,6 +87,11 @@ properties:
           - const: firefly,firefly-rk3399
           - const: rockchip,rk3399
 
+      - description: Firefly ROC-RK3308-CC
+        items:
+          - const: firefly,roc-rk3308-cc
+          - const: rockchip,rk3308
+
       - description: Firefly roc-rk3328-cc
         items:
           - const: firefly,roc-rk3328-cc
@@ -89,7 +99,9 @@ properties:
 
       - description: Firefly ROC-RK3399-PC
         items:
-          - const: firefly,roc-rk3399-pc
+          - enum:
+              - firefly,roc-rk3399-pc
+              - firefly,roc-rk3399-pc-mezzanine
           - const: rockchip,rk3399
 
       - description: FriendlyElec NanoPi4 series boards
@@ -464,6 +476,11 @@ properties:
               - rockchip,rk3288-evb-rk808
           - const: rockchip,rk3288
 
+      - description: Rockchip RK3308 Evaluation board
+        items:
+          - const: rockchip,rk3308-evb
+          - const: rockchip,rk3308
+
       - description: Rockchip RK3328 Evaluation board
         items:
           - const: rockchip,rk3328-evb
index 972b1e9..cffe8bb 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner platforms device tree bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   $nodename:
@@ -211,6 +211,11 @@ properties:
           - const: friendlyarm,nanopi-a64
           - const: allwinner,sun50i-a64
 
+      - description: FriendlyARM NanoPi Duo2
+        items:
+          - const: friendlyarm,nanopi-duo2
+          - const: allwinner,sun8i-h3
+
       - description: FriendlyARM NanoPi M1
         items:
           - const: friendlyarm,nanopi-m1
index 1464a47..2005bb4 100644 (file)
@@ -8,6 +8,7 @@ bus.
 Required properties:
  - compatible: Must be one of:
        - allwinner,sun5i-a13-mbus
+       - allwinner,sun8i-h3-mbus
  - reg: Offset and length of the register set for the controller
  - clocks: phandle to the clock driving the controller
  - dma-ranges: See section 2.3.9 of the DeviceTree Specification
index d2a8722..f0b3d30 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A64 Display Engine Bus Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   $nodename:
index be32f08..9fe11ce 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A23 RSB Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#address-cells":
index 64938fd..4d38212 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner Clock Control Unit Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#clock-cells":
index 39f0c1a..55e78cd 100644 (file)
@@ -10,6 +10,11 @@ Required Properties:
 - compatible: CRU should be "rockchip,px30-cru"
 - reg: physical base address of the controller and length of memory mapped
   region.
+- clocks: A list of phandle + clock-specifier pairs for the clocks listed
+          in clock-names
+- clock-names: Should contain the following:
+  - "xin24m" for both PMUCRU and CRU
+  - "gpll" for CRU (sourced from PMUCRU)
 - #clock-cells: should be 1.
 - #reset-cells: should be 1.
 
index 80b3e73..33c7842 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Security System Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml b/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml
new file mode 100644 (file)
index 0000000..2c459b8
--- /dev/null
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/crypto/allwinner,sun8i-ce.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner Crypto Engine driver
+
+maintainers:
+  - Corentin Labbe <clabbe.montjoie@gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - allwinner,sun8i-h3-crypto
+      - allwinner,sun8i-r40-crypto
+      - allwinner,sun50i-a64-crypto
+      - allwinner,sun50i-h5-crypto
+      - allwinner,sun50i-h6-crypto
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Bus clock
+      - description: Module clock
+      - description: MBus clock
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: bus
+      - const: mod
+      - const: ram
+    minItems: 2
+    maxItems: 3
+
+  resets:
+    maxItems: 1
+
+if:
+  properties:
+    compatible:
+      items:
+        const: allwinner,sun50i-h6-crypto
+then:
+  properties:
+      clocks:
+        minItems: 3
+      clock-names:
+        minItems: 3
+else:
+  properties:
+      clocks:
+        maxItems: 2
+      clock-names:
+        maxItems: 2
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/sun50i-a64-ccu.h>
+    #include <dt-bindings/reset/sun50i-a64-ccu.h>
+
+    crypto: crypto@1c15000 {
+      compatible = "allwinner,sun8i-h3-crypto";
+      reg = <0x01c15000 0x1000>;
+      interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>;
+      clock-names = "bus", "mod";
+      resets = <&ccu RST_BUS_CE>;
+    };
+
@@ -36,7 +36,7 @@ Child nodes:
   "lpddr2-timings" provides AC timing parameters of the device for
   a given speed-bin. The user may provide the timings for as many
   speed-bins as is required. Please see Documentation/devicetree/
-  bindings/lpddr2/lpddr2-timings.txt for more information on "lpddr2-timings"
+  bindings/ddr/lpddr2-timings.txt for more information on "lpddr2-timings"
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/ddr/lpddr3-timings.txt b/Documentation/devicetree/bindings/ddr/lpddr3-timings.txt
new file mode 100644 (file)
index 0000000..84705e5
--- /dev/null
@@ -0,0 +1,58 @@
+* AC timing parameters of LPDDR3 memories for a given speed-bin.
+
+The structures are based on LPDDR2 and extended where needed.
+
+Required properties:
+- compatible : Should be "jedec,lpddr3-timings"
+- min-freq : minimum DDR clock frequency for the speed-bin. Type is <u32>
+- reg : maximum DDR clock frequency for the speed-bin. Type is <u32>
+
+Optional properties:
+
+The following properties represent AC timing parameters from the memory
+data-sheet of the device for a given speed-bin. All these properties are
+of type <u32> and the default unit is ps (pico seconds).
+- tRFC
+- tRRD
+- tRPab
+- tRPpb
+- tRCD
+- tRC
+- tRAS
+- tWTR
+- tWR
+- tRTP
+- tW2W-C2C
+- tR2R-C2C
+- tFAW
+- tXSR
+- tXP
+- tCKE
+- tCKESR
+- tMRD
+
+Example:
+
+timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
+       compatible      = "jedec,lpddr3-timings";
+       reg             = <800000000>; /* workaround: it shows max-freq */
+       min-freq        = <100000000>;
+       tRFC            = <65000>;
+       tRRD            = <6000>;
+       tRPab           = <12000>;
+       tRPpb           = <12000>;
+       tRCD            = <10000>;
+       tRC             = <33750>;
+       tRAS            = <23000>;
+       tWTR            = <3750>;
+       tWR             = <7500>;
+       tRTP            = <3750>;
+       tW2W-C2C        = <0>;
+       tR2R-C2C        = <0>;
+       tFAW            = <25000>;
+       tXSR            = <70000>;
+       tXP             = <3750>;
+       tCKE            = <3750>;
+       tCKESR          = <3750>;
+       tMRD            = <7000>;
+};
diff --git a/Documentation/devicetree/bindings/ddr/lpddr3.txt b/Documentation/devicetree/bindings/ddr/lpddr3.txt
new file mode 100644 (file)
index 0000000..a0eda35
--- /dev/null
@@ -0,0 +1,101 @@
+* LPDDR3 SDRAM memories compliant to JEDEC JESD209-3C
+
+Required properties:
+- compatible : Should be "<vendor>,<type>", and generic value "jedec,lpddr3".
+  Example "<vendor>,<type>" values:
+    "samsung,K3QF2F20DB"
+
+- density  : <u32> representing density in Mb (Mega bits)
+- io-width : <u32> representing bus width. Possible values are 8, 16, 32, 64
+- #address-cells: Must be set to 1
+- #size-cells: Must be set to 0
+
+Optional properties:
+
+The following optional properties represent the minimum value of some AC
+timing parameters of the DDR device in terms of number of clock cycles.
+These values shall be obtained from the device data-sheet.
+- tRFC-min-tck
+- tRRD-min-tck
+- tRPab-min-tck
+- tRPpb-min-tck
+- tRCD-min-tck
+- tRC-min-tck
+- tRAS-min-tck
+- tWTR-min-tck
+- tWR-min-tck
+- tRTP-min-tck
+- tW2W-C2C-min-tck
+- tR2R-C2C-min-tck
+- tWL-min-tck
+- tDQSCK-min-tck
+- tRL-min-tck
+- tFAW-min-tck
+- tXSR-min-tck
+- tXP-min-tck
+- tCKE-min-tck
+- tCKESR-min-tck
+- tMRD-min-tck
+
+Child nodes:
+- The lpddr3 node may have one or more child nodes of type "lpddr3-timings".
+  "lpddr3-timings" provides AC timing parameters of the device for
+  a given speed-bin. Please see Documentation/devicetree/
+  bindings/ddr/lpddr3-timings.txt for more information on "lpddr3-timings"
+
+Example:
+
+samsung_K3QF2F20DB: lpddr3 {
+       compatible      = "samsung,K3QF2F20DB", "jedec,lpddr3";
+       density         = <16384>;
+       io-width        = <32>;
+       #address-cells  = <1>;
+       #size-cells     = <0>;
+
+       tRFC-min-tck            = <17>;
+       tRRD-min-tck            = <2>;
+       tRPab-min-tck           = <2>;
+       tRPpb-min-tck           = <2>;
+       tRCD-min-tck            = <3>;
+       tRC-min-tck             = <6>;
+       tRAS-min-tck            = <5>;
+       tWTR-min-tck            = <2>;
+       tWR-min-tck             = <7>;
+       tRTP-min-tck            = <2>;
+       tW2W-C2C-min-tck        = <0>;
+       tR2R-C2C-min-tck        = <0>;
+       tWL-min-tck             = <8>;
+       tDQSCK-min-tck          = <5>;
+       tRL-min-tck             = <14>;
+       tFAW-min-tck            = <5>;
+       tXSR-min-tck            = <12>;
+       tXP-min-tck             = <2>;
+       tCKE-min-tck            = <2>;
+       tCKESR-min-tck          = <2>;
+       tMRD-min-tck            = <5>;
+
+       timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
+               compatible      = "jedec,lpddr3-timings";
+               /* workaround: 'reg' shows max-freq */
+               reg             = <800000000>;
+               min-freq        = <100000000>;
+               tRFC            = <65000>;
+               tRRD            = <6000>;
+               tRPab           = <12000>;
+               tRPpb           = <12000>;
+               tRCD            = <10000>;
+               tRC             = <33750>;
+               tRAS            = <23000>;
+               tWTR            = <3750>;
+               tWR             = <7500>;
+               tRTP            = <3750>;
+               tW2W-C2C        = <0>;
+               tR2R-C2C        = <0>;
+               tFAW            = <25000>;
+               tXSR            = <70000>;
+               tXP             = <3750>;
+               tCKE            = <3750>;
+               tCKESR          = <3750>;
+               tMRD            = <7000>;
+       };
+}
index dafc098..0f70749 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A31 MIPI-DSI Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#address-cells": true
diff --git a/Documentation/devicetree/bindings/display/bridge/anx6345.yaml b/Documentation/devicetree/bindings/display/bridge/anx6345.yaml
new file mode 100644 (file)
index 0000000..6d72b3d
--- /dev/null
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/anx6345.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analogix ANX6345 eDP Transmitter Device Tree Bindings
+
+maintainers:
+  - Torsten Duwe <duwe@lst.de>
+
+description: |
+  The ANX6345 is an ultra-low power Full-HD eDP transmitter designed for
+  portable devices.
+
+properties:
+  compatible:
+    const: analogix,anx6345
+
+  reg:
+    maxItems: 1
+    description: base I2C address of the device
+
+  reset-gpios:
+    maxItems: 1
+    description: GPIO connected to active low reset
+
+  dvdd12-supply:
+    maxItems: 1
+    description: Regulator for 1.2V digital core power.
+
+  dvdd25-supply:
+    maxItems: 1
+    description: Regulator for 2.5V digital core power.
+
+  ports:
+    type: object
+
+    properties:
+      port@0:
+        type: object
+        description: |
+          Video port for LVTTL input
+
+      port@1:
+        type: object
+        description: |
+          Video port for eDP output (panel or connector).
+          May be omitted if EDID works reliably.
+
+    required:
+      - port@0
+
+required:
+  - compatible
+  - reg
+  - reset-gpios
+  - dvdd12-supply
+  - dvdd25-supply
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c0 {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      anx6345: anx6345@38 {
+        compatible = "analogix,anx6345";
+        reg = <0x38>;
+        reset-gpios = <&pio42 1 /* GPIO_ACTIVE_LOW */>;
+        dvdd25-supply = <&reg_dldo2>;
+        dvdd12-supply = <&reg_fldo1>;
+
+        ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          anx6345_in: port@0 {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            reg = <0>;
+            anx6345_in_tcon0: endpoint@0 {
+              reg = <0>;
+              remote-endpoint = <&tcon0_out_anx6345>;
+            };
+          };
+
+          anx6345_out: port@1 {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            reg = <1>;
+            anx6345_out_panel: endpoint@0 {
+              reg = <0>;
+              remote-endpoint = <&panel_in_edp>;
+            };
+          };
+        };
+      };
+    };
index 90af5b0..bf9c7a2 100644 (file)
@@ -31,6 +31,10 @@ Required properties:
 - iommus: phandle to the adreno iommu
 - operating-points-v2: phandle to the OPP operating points
 
+Optional properties:
+- sram: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon
+        SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml.
+
 Example:
 
 / {
@@ -63,3 +67,50 @@ Example:
                operating-points-v2 = <&gmu_opp_table>;
        };
 };
+
+a3xx example with OCMEM support:
+
+/ {
+       ...
+
+       gpu: adreno@fdb00000 {
+               compatible = "qcom,adreno-330.2",
+                            "qcom,adreno";
+               reg = <0xfdb00000 0x10000>;
+               reg-names = "kgsl_3d0_reg_memory";
+               interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "kgsl_3d0_irq";
+               clock-names = "core",
+                             "iface",
+                             "mem_iface";
+               clocks = <&mmcc OXILI_GFX3D_CLK>,
+                        <&mmcc OXILICX_AHB_CLK>,
+                        <&mmcc OXILICX_AXI_CLK>;
+               sram = <&gmu_sram>;
+               power-domains = <&mmcc OXILICX_GDSC>;
+               operating-points-v2 = <&gpu_opp_table>;
+               iommus = <&gpu_iommu 0>;
+       };
+
+       ocmem@fdd00000 {
+               compatible = "qcom,msm8974-ocmem";
+
+               reg = <0xfdd00000 0x2000>,
+                     <0xfec00000 0x180000>;
+               reg-names = "ctrl",
+                            "mem";
+
+               clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
+                        <&mmcc OCMEMCX_OCMEMNOC_CLK>;
+               clock-names = "core",
+                             "iface";
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               gmu_sram: gmu-sram@0 {
+                       reg = <0x0 0x100000>;
+                       ranges = <0 0 0xfec00000 0x100000>;
+               };
+       };
+};
index 4e11338..43d1127 100644 (file)
@@ -76,6 +76,8 @@ Required properties:
 Optional properties:
 - clock-names: the following clocks are optional:
   * "lut"
+  * "tbu"
+  * "tbu_rt"
 
 Example:
 
index 0e7987f..d67617f 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Ronbo RB070D30 DSI Display Panel
 
 maintainers:
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 15abc0f..8380819 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 DMA Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: "dma-controller.yaml#"
index 387d599..9e53472 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A64 DMA Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: "dma-controller.yaml#"
index 740b7f9..c1676b9 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A31 DMA Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: "dma-controller.yaml#"
index a4fe136..18c3aea 100644 (file)
@@ -11,7 +11,9 @@ power management service, FPGA service and other platform management
 services.
 
 Required properties:
- - compatible: Must contain:   "xlnx,zynqmp-firmware"
+ - compatible: Must contain any of below:
+               "xlnx,zynqmp-firmware" for Zynq Ultrascale+ MPSoC
+               "xlnx,versal-firmware" for Versal
  - method:     The method of calling the PM-API firmware layer.
                Permitted values are:
                  - "smc" : SMC #0, following the SMCCC
@@ -21,6 +23,8 @@ Required properties:
 Example
 -------
 
+Zynq Ultrascale+ MPSoC
+----------------------
 firmware {
        zynqmp_firmware: zynqmp-firmware {
                compatible = "xlnx,zynqmp-firmware";
@@ -28,3 +32,13 @@ firmware {
                ...
        };
 };
+
+Versal
+------
+firmware {
+       versal_firmware: versal-firmware {
+               compatible = "xlnx,versal-firmware";
+               method = "smc";
+               ...
+       };
+};
index c9bdf10..36f59b3 100644 (file)
@@ -33,6 +33,10 @@ properties:
           - const: arm,mali-t820
       - items:
           - enum:
+             - arm,juno-mali
+          - const: arm,mali-t624
+      - items:
+          - enum:
              - rockchip,rk3288-mali
              - samsung,exynos5433-mali
           - const: arm,mali-t760
@@ -41,7 +45,6 @@ properties:
              - rockchip,rk3399-mali
           - const: arm,mali-t860
 
-          # "arm,mali-t624"
           # "arm,mali-t830"
           # "arm,mali-t880"
 
index 9346ef6..6097e8a 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A31 P2WI (Push/Pull 2 Wires Interface) Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: /schemas/i2c/i2c-controller.yaml#
index b68be3a..e1f6d64 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/iio/adc/adi,ad7292.yaml#
@@ -53,7 +53,8 @@ patternProperties:
         description: |
           The channel number. It can have up to 8 channels numbered from 0 to 7.
         items:
-          maximum: 7
+          - minimum: 0
+            maximum: 7
 
       diff-channels:
         description: see Documentation/devicetree/bindings/iio/adc/adc.txt
index d74962c..15c514b 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A33 Thermal Sensor Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#io-channel-cells":
index b3bd8ef..5b3b71c 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 LRADC Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 23a202d..953d875 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Interrupt Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: /schemas/interrupt-controller.yaml#
index 8cd08cf..cf09055 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A20 Non-Maskable Interrupt Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: /schemas/interrupt-controller.yaml#
index 608fee1..a0ed027 100644 (file)
@@ -1,13 +1,17 @@
 * Marvell MMP Interrupt controller
 
 Required properties:
-- compatible : Should be "mrvl,mmp-intc", "mrvl,mmp2-intc" or
-  "mrvl,mmp2-mux-intc"
+- compatible : Should be
+               "mrvl,mmp-intc" on Marvel MMP,
+               "mrvl,mmp2-intc" along with "mrvl,mmp2-mux-intc" on MMP2 or
+               "marvell,mmp3-intc" with "mrvl,mmp2-mux-intc" on MMP3
 - reg : Address and length of the register set of the interrupt controller.
   If the interrupt controller is intc, address and length means the range
-  of the whole interrupt controller. If the interrupt controller is mux-intc,
-  address and length means one register. Since address of mux-intc is in the
-  range of intc. mux-intc is secondary interrupt controller.
+  of the whole interrupt controller. The "marvell,mmp3-intc" controller
+  also has a secondary range for the second CPU core.  If the interrupt
+  controller is mux-intc, address and length means one register. Since
+  address of mux-intc is in the range of intc. mux-intc is secondary
+  interrupt controller.
 - reg-names : Name of the register set of the interrupt controller. It's
   only required in mux-intc interrupt controller.
 - interrupts : Should be the port interrupt shared by mux interrupts. It's
index d3e423f..0f6374c 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 CMOS Sensor Interface (CSI) Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 description: |-
   The Allwinner A10 and later has a CMOS Sensor Interface to retrieve
index dea36d6..7838804 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Infrared Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: "rc.yaml#"
diff --git a/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt b/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
new file mode 100644 (file)
index 0000000..02e4a1f
--- /dev/null
@@ -0,0 +1,84 @@
+* Exynos5422 frequency and voltage scaling for Dynamic Memory Controller device
+
+The Samsung Exynos5422 SoC has DMC (Dynamic Memory Controller) to which the DRAM
+memory chips are connected. The driver is to monitor the controller in runtime
+and switch frequency and voltage. To monitor the usage of the controller in
+runtime, the driver uses the PPMU (Platform Performance Monitoring Unit), which
+is able to measure the current load of the memory.
+When 'userspace' governor is used for the driver, an application is able to
+switch the DMC and memory frequency.
+
+Required properties for DMC device for Exynos5422:
+- compatible: Should be "samsung,exynos5422-dmc".
+- clocks : list of clock specifiers, must contain an entry for each
+  required entry in clock-names for CLK_FOUT_SPLL, CLK_MOUT_SCLK_SPLL,
+  CLK_FF_DOUT_SPLL2, CLK_FOUT_BPLL, CLK_MOUT_BPLL, CLK_SCLK_BPLL,
+  CLK_MOUT_MX_MSPLL_CCORE, CLK_MOUT_MX_MSPLL_CCORE_PHY, CLK_MOUT_MCLK_CDREX,
+- clock-names : should include "fout_spll", "mout_sclk_spll", "ff_dout_spll2",
+  "fout_bpll", "mout_bpll", "sclk_bpll", "mout_mx_mspll_ccore",
+  "mout_mclk_cdrex"  entries
+- devfreq-events : phandles for PPMU devices connected to this DMC.
+- vdd-supply : phandle for voltage regulator which is connected.
+- reg : registers of two CDREX controllers.
+- operating-points-v2 : phandle for OPPs described in v2 definition.
+- device-handle : phandle of the connected DRAM memory device. For more
+       information please refer to documentation file:
+       Documentation/devicetree/bindings/ddr/lpddr3.txt
+- devfreq-events : phandles of the PPMU events used by the controller.
+- samsung,syscon-clk : phandle of the clock register set used by the controller,
+       these registers are used for enabling a 'pause' feature and are not
+       exposed by clock framework but they must be used in a safe way.
+       The register offsets are in the driver code and specyfic for this SoC
+       type.
+
+Optional properties for DMC device for Exynos5422:
+- interrupt-parent : The parent interrupt controller.
+- interrupts : Contains the IRQ line numbers for the DMC internal performance
+  event counters in DREX0 and DREX1 channels. Align with specification of the
+  interrupt line(s) in the interrupt-parent controller.
+- interrupt-names : IRQ names "drex_0" and "drex_1", the order should be the
+  same as in the 'interrupts' list above.
+
+Example:
+
+       ppmu_dmc0_0: ppmu@10d00000 {
+               compatible = "samsung,exynos-ppmu";
+               reg = <0x10d00000 0x2000>;
+               clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
+               clock-names = "ppmu";
+               events {
+                       ppmu_event_dmc0_0: ppmu-event3-dmc0_0 {
+                               event-name = "ppmu-event3-dmc0_0";
+                       };
+               };
+       };
+
+       dmc: memory-controller@10c20000 {
+               compatible = "samsung,exynos5422-dmc";
+               reg = <0x10c20000 0x10000>, <0x10c30000 0x10000>;
+               clocks = <&clock CLK_FOUT_SPLL>,
+                        <&clock CLK_MOUT_SCLK_SPLL>,
+                        <&clock CLK_FF_DOUT_SPLL2>,
+                        <&clock CLK_FOUT_BPLL>,
+                        <&clock CLK_MOUT_BPLL>,
+                        <&clock CLK_SCLK_BPLL>,
+                        <&clock CLK_MOUT_MX_MSPLL_CCORE>,
+                        <&clock CLK_MOUT_MCLK_CDREX>;
+               clock-names = "fout_spll",
+                             "mout_sclk_spll",
+                             "ff_dout_spll2",
+                             "fout_bpll",
+                             "mout_bpll",
+                             "sclk_bpll",
+                             "mout_mx_mspll_ccore",
+                             "mout_mclk_cdrex";
+               operating-points-v2 = <&dmc_opp_table>;
+               devfreq-events = <&ppmu_event3_dmc0_0>, <&ppmu_event3_dmc0_1>,
+                                <&ppmu_event3_dmc1_0>, <&ppmu_event3_dmc1_1>;
+               device-handle = <&samsung_K3QF2F20DB>;
+               vdd-supply = <&buck1_reg>;
+               samsung,syscon-clk = <&clock>;
+               interrupt-parent = <&combiner>;
+               interrupts = <16 0>, <16 1>;
+               interrupt-names = "drex_0", "drex_1";
+       };
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
new file mode 100644 (file)
index 0000000..22a94b6
--- /dev/null
@@ -0,0 +1,153 @@
+# SPDX-License-Identifier: (GPL-2.0)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra124-mc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra124 SoC Memory Controller
+
+maintainers:
+  - Jon Hunter <jonathanh@nvidia.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+description: |
+  Tegra124 SoC features a hybrid 2x32-bit / 1x64-bit memory controller.
+  These are interleaved to provide high performance with the load shared across
+  two memory channels. The Tegra124 Memory Controller handles memory requests
+  from internal clients and arbitrates among them to allocate memory bandwidth
+  for DDR3L and LPDDR3 SDRAMs.
+
+properties:
+  compatible:
+    const: nvidia,tegra124-mc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: mc
+
+  interrupts:
+    maxItems: 1
+
+  "#reset-cells":
+    const: 1
+
+  "#iommu-cells":
+    const: 1
+
+patternProperties:
+  "^emc-timings-[0-9]+$":
+    type: object
+    properties:
+      nvidia,ram-code:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          Value of RAM_CODE this timing set is used for.
+
+    patternProperties:
+      "^timing-[0-9]+$":
+        type: object
+        properties:
+          clock-frequency:
+            description:
+              Memory clock rate in Hz.
+            minimum: 1000000
+            maximum: 1066000000
+
+          nvidia,emem-configuration:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32-array
+            description: |
+              Values to be written to the EMEM register block. See section
+              "15.6.1 MC Registers" in the TRM.
+            items:
+              - description: MC_EMEM_ARB_CFG
+              - description: MC_EMEM_ARB_OUTSTANDING_REQ
+              - description: MC_EMEM_ARB_TIMING_RCD
+              - description: MC_EMEM_ARB_TIMING_RP
+              - description: MC_EMEM_ARB_TIMING_RC
+              - description: MC_EMEM_ARB_TIMING_RAS
+              - description: MC_EMEM_ARB_TIMING_FAW
+              - description: MC_EMEM_ARB_TIMING_RRD
+              - description: MC_EMEM_ARB_TIMING_RAP2PRE
+              - description: MC_EMEM_ARB_TIMING_WAP2PRE
+              - description: MC_EMEM_ARB_TIMING_R2R
+              - description: MC_EMEM_ARB_TIMING_W2W
+              - description: MC_EMEM_ARB_TIMING_R2W
+              - description: MC_EMEM_ARB_TIMING_W2R
+              - description: MC_EMEM_ARB_DA_TURNS
+              - description: MC_EMEM_ARB_DA_COVERS
+              - description: MC_EMEM_ARB_MISC0
+              - description: MC_EMEM_ARB_MISC1
+              - description: MC_EMEM_ARB_RING1_THROTTLE
+
+        required:
+          - clock-frequency
+          - nvidia,emem-configuration
+
+        additionalProperties: false
+
+    required:
+      - nvidia,ram-code
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - "#reset-cells"
+  - "#iommu-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    memory-controller@70019000 {
+        compatible = "nvidia,tegra124-mc";
+        reg = <0x0 0x70019000 0x0 0x1000>;
+        clocks = <&tegra_car 32>;
+        clock-names = "mc";
+
+        interrupts = <0 77 4>;
+
+        #iommu-cells = <1>;
+        #reset-cells = <1>;
+
+        emc-timings-3 {
+            nvidia,ram-code = <3>;
+
+            timing-12750000 {
+                clock-frequency = <12750000>;
+
+                nvidia,emem-configuration = <
+                    0x40040001 /* MC_EMEM_ARB_CFG */
+                    0x8000000a /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                    0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                    0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                    0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                    0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                    0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                    0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                    0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                    0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                    0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                    0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                    0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                    0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                    0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                    0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                    0x77e30303 /* MC_EMEM_ARB_MISC0 */
+                    0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                    0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                >;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
new file mode 100644 (file)
index 0000000..e4135ba
--- /dev/null
@@ -0,0 +1,339 @@
+# SPDX-License-Identifier: (GPL-2.0)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra30-emc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra30 SoC External Memory Controller
+
+maintainers:
+  - Dmitry Osipenko <digetx@gmail.com>
+  - Jon Hunter <jonathanh@nvidia.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+description: |
+  The EMC interfaces with the off-chip SDRAM to service the request stream
+  sent from Memory Controller. The EMC also has various performance-affecting
+  settings beyond the obvious SDRAM configuration parameters and initialization
+  settings. Tegra30 EMC supports multiple JEDEC standard protocols: LPDDR2,
+  LPDDR3, and DDR3.
+
+properties:
+  compatible:
+    const: nvidia,tegra30-emc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  nvidia,memory-controller:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle of the Memory Controller node.
+
+patternProperties:
+  "^emc-timings-[0-9]+$":
+    type: object
+    properties:
+      nvidia,ram-code:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          Value of RAM_CODE this timing set is used for.
+
+    patternProperties:
+      "^timing-[0-9]+$":
+        type: object
+        properties:
+          clock-frequency:
+            description:
+              Memory clock rate in Hz.
+            minimum: 1000000
+            maximum: 900000000
+
+          nvidia,emc-auto-cal-interval:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              Pad calibration interval in microseconds.
+            minimum: 0
+            maximum: 2097151
+
+          nvidia,emc-mode-1:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              Mode Register 1.
+
+          nvidia,emc-mode-2:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              Mode Register 2.
+
+          nvidia,emc-mode-reset:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              Mode Register 0.
+
+          nvidia,emc-zcal-cnt-long:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              Number of EMC clocks to wait before issuing any commands after
+              sending ZCAL_MRW_CMD.
+            minimum: 0
+            maximum: 1023
+
+          nvidia,emc-cfg-dyn-self-ref:
+            type: boolean
+            description:
+              Dynamic self-refresh enabled.
+
+          nvidia,emc-cfg-periodic-qrst:
+            type: boolean
+            description:
+              FBIO "read" FIFO periodic resetting enabled.
+
+          nvidia,emc-configuration:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32-array
+            description:
+              EMC timing characterization data. These are the registers
+              (see section "18.13.2 EMC Registers" in the TRM) whose values
+              need to be specified, according to the board documentation.
+            items:
+              - description: EMC_RC
+              - description: EMC_RFC
+              - description: EMC_RAS
+              - description: EMC_RP
+              - description: EMC_R2W
+              - description: EMC_W2R
+              - description: EMC_R2P
+              - description: EMC_W2P
+              - description: EMC_RD_RCD
+              - description: EMC_WR_RCD
+              - description: EMC_RRD
+              - description: EMC_REXT
+              - description: EMC_WEXT
+              - description: EMC_WDV
+              - description: EMC_QUSE
+              - description: EMC_QRST
+              - description: EMC_QSAFE
+              - description: EMC_RDV
+              - description: EMC_REFRESH
+              - description: EMC_BURST_REFRESH_NUM
+              - description: EMC_PRE_REFRESH_REQ_CNT
+              - description: EMC_PDEX2WR
+              - description: EMC_PDEX2RD
+              - description: EMC_PCHG2PDEN
+              - description: EMC_ACT2PDEN
+              - description: EMC_AR2PDEN
+              - description: EMC_RW2PDEN
+              - description: EMC_TXSR
+              - description: EMC_TXSRDLL
+              - description: EMC_TCKE
+              - description: EMC_TFAW
+              - description: EMC_TRPAB
+              - description: EMC_TCLKSTABLE
+              - description: EMC_TCLKSTOP
+              - description: EMC_TREFBW
+              - description: EMC_QUSE_EXTRA
+              - description: EMC_FBIO_CFG6
+              - description: EMC_ODT_WRITE
+              - description: EMC_ODT_READ
+              - description: EMC_FBIO_CFG5
+              - description: EMC_CFG_DIG_DLL
+              - description: EMC_CFG_DIG_DLL_PERIOD
+              - description: EMC_DLL_XFORM_DQS0
+              - description: EMC_DLL_XFORM_DQS1
+              - description: EMC_DLL_XFORM_DQS2
+              - description: EMC_DLL_XFORM_DQS3
+              - description: EMC_DLL_XFORM_DQS4
+              - description: EMC_DLL_XFORM_DQS5
+              - description: EMC_DLL_XFORM_DQS6
+              - description: EMC_DLL_XFORM_DQS7
+              - description: EMC_DLL_XFORM_QUSE0
+              - description: EMC_DLL_XFORM_QUSE1
+              - description: EMC_DLL_XFORM_QUSE2
+              - description: EMC_DLL_XFORM_QUSE3
+              - description: EMC_DLL_XFORM_QUSE4
+              - description: EMC_DLL_XFORM_QUSE5
+              - description: EMC_DLL_XFORM_QUSE6
+              - description: EMC_DLL_XFORM_QUSE7
+              - description: EMC_DLI_TRIM_TXDQS0
+              - description: EMC_DLI_TRIM_TXDQS1
+              - description: EMC_DLI_TRIM_TXDQS2
+              - description: EMC_DLI_TRIM_TXDQS3
+              - description: EMC_DLI_TRIM_TXDQS4
+              - description: EMC_DLI_TRIM_TXDQS5
+              - description: EMC_DLI_TRIM_TXDQS6
+              - description: EMC_DLI_TRIM_TXDQS7
+              - description: EMC_DLL_XFORM_DQ0
+              - description: EMC_DLL_XFORM_DQ1
+              - description: EMC_DLL_XFORM_DQ2
+              - description: EMC_DLL_XFORM_DQ3
+              - description: EMC_XM2CMDPADCTRL
+              - description: EMC_XM2DQSPADCTRL2
+              - description: EMC_XM2DQPADCTRL2
+              - description: EMC_XM2CLKPADCTRL
+              - description: EMC_XM2COMPPADCTRL
+              - description: EMC_XM2VTTGENPADCTRL
+              - description: EMC_XM2VTTGENPADCTRL2
+              - description: EMC_XM2QUSEPADCTRL
+              - description: EMC_XM2DQSPADCTRL3
+              - description: EMC_CTT_TERM_CTRL
+              - description: EMC_ZCAL_INTERVAL
+              - description: EMC_ZCAL_WAIT_CNT
+              - description: EMC_MRS_WAIT_CNT
+              - description: EMC_AUTO_CAL_CONFIG
+              - description: EMC_CTT
+              - description: EMC_CTT_DURATION
+              - description: EMC_DYN_SELF_REF_CONTROL
+              - description: EMC_FBIO_SPARE
+              - description: EMC_CFG_RSV
+
+        required:
+          - clock-frequency
+          - nvidia,emc-auto-cal-interval
+          - nvidia,emc-mode-1
+          - nvidia,emc-mode-2
+          - nvidia,emc-mode-reset
+          - nvidia,emc-zcal-cnt-long
+          - nvidia,emc-configuration
+
+        additionalProperties: false
+
+    required:
+      - nvidia,ram-code
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - nvidia,memory-controller
+
+additionalProperties: false
+
+examples:
+  - |
+    external-memory-controller@7000f400 {
+        compatible = "nvidia,tegra30-emc";
+        reg = <0x7000f400 0x400>;
+        interrupts = <0 78 4>;
+        clocks = <&tegra_car 57>;
+
+        nvidia,memory-controller = <&mc>;
+
+        emc-timings-1 {
+            nvidia,ram-code = <1>;
+
+            timing-667000000 {
+                clock-frequency = <667000000>;
+
+                nvidia,emc-auto-cal-interval = <0x001fffff>;
+                nvidia,emc-mode-1 = <0x80100002>;
+                nvidia,emc-mode-2 = <0x80200018>;
+                nvidia,emc-mode-reset = <0x80000b71>;
+                nvidia,emc-zcal-cnt-long = <0x00000040>;
+                nvidia,emc-cfg-periodic-qrst;
+
+                nvidia,emc-configuration = <
+                    0x00000020 /* EMC_RC */
+                    0x0000006a /* EMC_RFC */
+                    0x00000017 /* EMC_RAS */
+                    0x00000007 /* EMC_RP */
+                    0x00000005 /* EMC_R2W */
+                    0x0000000c /* EMC_W2R */
+                    0x00000003 /* EMC_R2P */
+                    0x00000011 /* EMC_W2P */
+                    0x00000007 /* EMC_RD_RCD */
+                    0x00000007 /* EMC_WR_RCD */
+                    0x00000002 /* EMC_RRD */
+                    0x00000001 /* EMC_REXT */
+                    0x00000000 /* EMC_WEXT */
+                    0x00000007 /* EMC_WDV */
+                    0x0000000a /* EMC_QUSE */
+                    0x00000009 /* EMC_QRST */
+                    0x0000000b /* EMC_QSAFE */
+                    0x00000011 /* EMC_RDV */
+                    0x00001412 /* EMC_REFRESH */
+                    0x00000000 /* EMC_BURST_REFRESH_NUM */
+                    0x00000504 /* EMC_PRE_REFRESH_REQ_CNT */
+                    0x00000002 /* EMC_PDEX2WR */
+                    0x0000000e /* EMC_PDEX2RD */
+                    0x00000001 /* EMC_PCHG2PDEN */
+                    0x00000000 /* EMC_ACT2PDEN */
+                    0x0000000c /* EMC_AR2PDEN */
+                    0x00000016 /* EMC_RW2PDEN */
+                    0x00000072 /* EMC_TXSR */
+                    0x00000200 /* EMC_TXSRDLL */
+                    0x00000005 /* EMC_TCKE */
+                    0x00000015 /* EMC_TFAW */
+                    0x00000000 /* EMC_TRPAB */
+                    0x00000006 /* EMC_TCLKSTABLE */
+                    0x00000007 /* EMC_TCLKSTOP */
+                    0x00001453 /* EMC_TREFBW */
+                    0x0000000b /* EMC_QUSE_EXTRA */
+                    0x00000006 /* EMC_FBIO_CFG6 */
+                    0x00000000 /* EMC_ODT_WRITE */
+                    0x00000000 /* EMC_ODT_READ */
+                    0x00005088 /* EMC_FBIO_CFG5 */
+                    0xf00b0191 /* EMC_CFG_DIG_DLL */
+                    0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                    0x00000008 /* EMC_DLL_XFORM_DQS0 */
+                    0x00000008 /* EMC_DLL_XFORM_DQS1 */
+                    0x00000008 /* EMC_DLL_XFORM_DQS2 */
+                    0x00000008 /* EMC_DLL_XFORM_DQS3 */
+                    0x0000000a /* EMC_DLL_XFORM_DQS4 */
+                    0x0000000a /* EMC_DLL_XFORM_DQS5 */
+                    0x0000000a /* EMC_DLL_XFORM_DQS6 */
+                    0x0000000a /* EMC_DLL_XFORM_DQS7 */
+                    0x00018000 /* EMC_DLL_XFORM_QUSE0 */
+                    0x00018000 /* EMC_DLL_XFORM_QUSE1 */
+                    0x00018000 /* EMC_DLL_XFORM_QUSE2 */
+                    0x00018000 /* EMC_DLL_XFORM_QUSE3 */
+                    0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                    0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                    0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                    0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                    0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                    0x0000000a /* EMC_DLL_XFORM_DQ0 */
+                    0x0000000a /* EMC_DLL_XFORM_DQ1 */
+                    0x0000000a /* EMC_DLL_XFORM_DQ2 */
+                    0x0000000a /* EMC_DLL_XFORM_DQ3 */
+                    0x000002a0 /* EMC_XM2CMDPADCTRL */
+                    0x0800013d /* EMC_XM2DQSPADCTRL2 */
+                    0x22220000 /* EMC_XM2DQPADCTRL2 */
+                    0x77fff884 /* EMC_XM2CLKPADCTRL */
+                    0x01f1f501 /* EMC_XM2COMPPADCTRL */
+                    0x07077404 /* EMC_XM2VTTGENPADCTRL */
+                    0x54000000 /* EMC_XM2VTTGENPADCTRL2 */
+                    0x080001e8 /* EMC_XM2QUSEPADCTRL */
+                    0x0c000021 /* EMC_XM2DQSPADCTRL3 */
+                    0x00000802 /* EMC_CTT_TERM_CTRL */
+                    0x00020000 /* EMC_ZCAL_INTERVAL */
+                    0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                    0x0155000c /* EMC_MRS_WAIT_CNT */
+                    0xa0f10000 /* EMC_AUTO_CAL_CONFIG */
+                    0x00000000 /* EMC_CTT */
+                    0x00000000 /* EMC_CTT_DURATION */
+                    0x800028a5 /* EMC_DYN_SELF_REF_CONTROL */
+                    0xe8000000 /* EMC_FBIO_SPARE */
+                    0xff00ff49 /* EMC_CFG_RSV */
+                >;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt
deleted file mode 100644 (file)
index a878b59..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-NVIDIA Tegra Memory Controller device tree bindings
-===================================================
-
-memory-controller node
-----------------------
-
-Required properties:
-- compatible: Should be "nvidia,tegra<chip>-mc"
-- reg: Physical base address and length of the controller's registers.
-- clocks: Must contain an entry for each entry in clock-names.
-  See ../clocks/clock-bindings.txt for details.
-- clock-names: Must include the following entries:
-  - mc: the module's clock input
-- interrupts: The interrupt outputs from the controller.
-- #reset-cells : Should be 1. This cell represents memory client module ID.
-  The assignments may be found in header file <dt-bindings/memory/tegra30-mc.h>
-  or in the TRM documentation.
-
-Required properties for Tegra30, Tegra114, Tegra124, Tegra132 and Tegra210:
-- #iommu-cells: Should be 1. The single cell of the IOMMU specifier defines
-  the SWGROUP of the master.
-
-This device implements an IOMMU that complies with the generic IOMMU binding.
-See ../iommu/iommu.txt for details.
-
-emc-timings subnode
--------------------
-
-The node should contain a "emc-timings" subnode for each supported RAM type (see field RAM_CODE in
-register PMC_STRAPPING_OPT_A).
-
-Required properties for "emc-timings" nodes :
-- nvidia,ram-code : Should contain the value of RAM_CODE this timing set is used for.
-
-timing subnode
---------------
-
-Each "emc-timings" node should contain a subnode for every supported EMC clock rate.
-
-Required properties for timing nodes :
-- clock-frequency : Should contain the memory clock rate in Hz.
-- nvidia,emem-configuration : Values to be written to the EMEM register block. For the Tegra124 SoC
-(see section "15.6.1 MC Registers" in the TRM), these are the registers whose values need to be
-specified, according to the board documentation:
-
-       MC_EMEM_ARB_CFG
-       MC_EMEM_ARB_OUTSTANDING_REQ
-       MC_EMEM_ARB_TIMING_RCD
-       MC_EMEM_ARB_TIMING_RP
-       MC_EMEM_ARB_TIMING_RC
-       MC_EMEM_ARB_TIMING_RAS
-       MC_EMEM_ARB_TIMING_FAW
-       MC_EMEM_ARB_TIMING_RRD
-       MC_EMEM_ARB_TIMING_RAP2PRE
-       MC_EMEM_ARB_TIMING_WAP2PRE
-       MC_EMEM_ARB_TIMING_R2R
-       MC_EMEM_ARB_TIMING_W2W
-       MC_EMEM_ARB_TIMING_R2W
-       MC_EMEM_ARB_TIMING_W2R
-       MC_EMEM_ARB_DA_TURNS
-       MC_EMEM_ARB_DA_COVERS
-       MC_EMEM_ARB_MISC0
-       MC_EMEM_ARB_MISC1
-       MC_EMEM_ARB_RING1_THROTTLE
-
-Example SoC include file:
-
-/ {
-       mc: memory-controller@70019000 {
-               compatible = "nvidia,tegra124-mc";
-               reg = <0x0 0x70019000 0x0 0x1000>;
-               clocks = <&tegra_car TEGRA124_CLK_MC>;
-               clock-names = "mc";
-
-               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
-
-               #iommu-cells = <1>;
-               #reset-cells = <1>;
-       };
-
-       sdhci@700b0000 {
-               compatible = "nvidia,tegra124-sdhci";
-               ...
-               iommus = <&mc TEGRA_SWGROUP_SDMMC1A>;
-               resets = <&mc TEGRA124_MC_RESET_SDMMC1>;
-       };
-};
-
-Example board file:
-
-/ {
-       memory-controller@70019000 {
-               emc-timings-3 {
-                       nvidia,ram-code = <3>;
-
-                       timing-12750000 {
-                               clock-frequency = <12750000>;
-
-                               nvidia,emem-configuration = <
-                                       0x40040001 /* MC_EMEM_ARB_CFG */
-                                       0x8000000a /* MC_EMEM_ARB_OUTSTANDING_REQ */
-                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
-                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
-                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
-                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
-                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
-                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
-                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
-                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
-                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
-                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
-                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
-                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
-                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
-                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
-                                       0x77e30303 /* MC_EMEM_ARB_MISC0 */
-                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
-                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
-                               >;
-                       };
-               };
-       };
-};
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
new file mode 100644 (file)
index 0000000..4b9196c
--- /dev/null
@@ -0,0 +1,168 @@
+# SPDX-License-Identifier: (GPL-2.0)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra30-mc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra30 SoC Memory Controller
+
+maintainers:
+  - Dmitry Osipenko <digetx@gmail.com>
+  - Jon Hunter <jonathanh@nvidia.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+description: |
+  Tegra30 Memory Controller architecturally consists of the following parts:
+
+    Arbitration Domains, which can handle a single request or response per
+    clock from a group of clients. Typically, a system has a single Arbitration
+    Domain, but an implementation may divide the client space into multiple
+    Arbitration Domains to increase the effective system bandwidth.
+
+    Protocol Arbiter, which manage a related pool of memory devices. A system
+    may have a single Protocol Arbiter or multiple Protocol Arbiters.
+
+    Memory Crossbar, which routes request and responses between Arbitration
+    Domains and Protocol Arbiters. In the simplest version of the system, the
+    Memory Crossbar is just a pass through between a single Arbitration Domain
+    and a single Protocol Arbiter.
+
+    Global Resources, which include things like configuration registers which
+    are shared across the Memory Subsystem.
+
+  The Tegra30 Memory Controller handles memory requests from internal clients
+  and arbitrates among them to allocate memory bandwidth for DDR3L and LPDDR2
+  SDRAMs.
+
+properties:
+  compatible:
+    const: nvidia,tegra30-mc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: mc
+
+  interrupts:
+    maxItems: 1
+
+  "#reset-cells":
+    const: 1
+
+  "#iommu-cells":
+    const: 1
+
+patternProperties:
+  "^emc-timings-[0-9]+$":
+    type: object
+    properties:
+      nvidia,ram-code:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          Value of RAM_CODE this timing set is used for.
+
+    patternProperties:
+      "^timing-[0-9]+$":
+        type: object
+        properties:
+          clock-frequency:
+            description:
+              Memory clock rate in Hz.
+            minimum: 1000000
+            maximum: 900000000
+
+          nvidia,emem-configuration:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32-array
+            description: |
+              Values to be written to the EMEM register block. See section
+              "18.13.1 MC Registers" in the TRM.
+            items:
+              - description: MC_EMEM_ARB_CFG
+              - description: MC_EMEM_ARB_OUTSTANDING_REQ
+              - description: MC_EMEM_ARB_TIMING_RCD
+              - description: MC_EMEM_ARB_TIMING_RP
+              - description: MC_EMEM_ARB_TIMING_RC
+              - description: MC_EMEM_ARB_TIMING_RAS
+              - description: MC_EMEM_ARB_TIMING_FAW
+              - description: MC_EMEM_ARB_TIMING_RRD
+              - description: MC_EMEM_ARB_TIMING_RAP2PRE
+              - description: MC_EMEM_ARB_TIMING_WAP2PRE
+              - description: MC_EMEM_ARB_TIMING_R2R
+              - description: MC_EMEM_ARB_TIMING_W2W
+              - description: MC_EMEM_ARB_TIMING_R2W
+              - description: MC_EMEM_ARB_TIMING_W2R
+              - description: MC_EMEM_ARB_DA_TURNS
+              - description: MC_EMEM_ARB_DA_COVERS
+              - description: MC_EMEM_ARB_MISC0
+              - description: MC_EMEM_ARB_RING1_THROTTLE
+
+        required:
+          - clock-frequency
+          - nvidia,emem-configuration
+
+        additionalProperties: false
+
+    required:
+      - nvidia,ram-code
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - "#reset-cells"
+  - "#iommu-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    memory-controller@7000f000 {
+        compatible = "nvidia,tegra30-mc";
+        reg = <0x7000f000 0x400>;
+        clocks = <&tegra_car 32>;
+        clock-names = "mc";
+
+        interrupts = <0 77 4>;
+
+        #iommu-cells = <1>;
+        #reset-cells = <1>;
+
+        emc-timings-1 {
+            nvidia,ram-code = <1>;
+
+            timing-667000000 {
+                clock-frequency = <667000000>;
+
+                nvidia,emem-configuration = <
+                    0x0000000a /* MC_EMEM_ARB_CFG */
+                    0xc0000079 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                    0x00000003 /* MC_EMEM_ARB_TIMING_RCD */
+                    0x00000004 /* MC_EMEM_ARB_TIMING_RP */
+                    0x00000010 /* MC_EMEM_ARB_TIMING_RC */
+                    0x0000000b /* MC_EMEM_ARB_TIMING_RAS */
+                    0x0000000a /* MC_EMEM_ARB_TIMING_FAW */
+                    0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                    0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                    0x0000000b /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                    0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                    0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                    0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                    0x00000008 /* MC_EMEM_ARB_TIMING_W2R */
+                    0x08040202 /* MC_EMEM_ARB_DA_TURNS */
+                    0x00130b10 /* MC_EMEM_ARB_DA_COVERS */
+                    0x70ea1f11 /* MC_EMEM_ARB_MISC0 */
+                    0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                >;
+            };
+        };
+    };
index 4b1a09a..39afacc 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Resistive Touchscreen Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#thermal-sensor-cells":
index 64bca41..e82c9a0 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#address-cells": true
index b5b3cf5..5d3fa41 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#address-cells": true
index ae4796e..8d8560a 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index e5562c5..767193e 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 MDIO Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: "mdio.yaml#"
index f683b71..703d0d8 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 11654d4..db36b4d 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A83t EMAC Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 770af7c..a95960e 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 CAN Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 81ae8ca..ac8c763 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/net/ti,cpsw-switch.yaml#
@@ -44,7 +44,6 @@ properties:
     description: CPSW functional clock
 
   clock-names:
-    maxItems: 1
     items:
       - const: fck
 
@@ -70,7 +69,6 @@ properties:
       Phandle to the system control device node which provides access to
       efuse IO range with MAC addresses
 
-
   ethernet-ports:
     type: object
     properties:
@@ -82,8 +80,6 @@ properties:
     patternProperties:
       "^port@[0-9]+$":
           type: object
-          minItems: 1
-          maxItems: 2
           description: CPSW external ports
 
           allOf:
@@ -91,23 +87,20 @@ properties:
 
           properties:
             reg:
-              maxItems: 1
-              enum: [1, 2]
+              items:
+                - enum: [1, 2]
               description: CPSW port number
 
             phys:
-              $ref: /schemas/types.yaml#definitions/phandle-array
               maxItems: 1
               description:  phandle on phy-gmii-sel PHY
 
             label:
-              $ref: /schemas/types.yaml#/definitions/string-array
-              maxItems: 1
               description: label associated with this port
 
             ti,dual-emac-pvid:
-              $ref: /schemas/types.yaml#/definitions/uint32
-              maxItems: 1
+              allOf:
+                - $ref: /schemas/types.yaml#/definitions/uint32
               minimum: 1
               maximum: 1024
               description:
@@ -136,7 +129,6 @@ properties:
         description: CPTS reference clock
 
       clock-names:
-        maxItems: 1
         items:
           - const: cpts
 
@@ -201,7 +193,7 @@ examples:
                         phys = <&phy_gmii_sel 1>;
                         phy-handle = <&ethphy0_sw>;
                         phy-mode = "rgmii";
-                        ti,dual_emac_pvid = <1>;
+                        ti,dual-emac-pvid = <1>;
                 };
 
                 cpsw_port2: port@2 {
@@ -211,7 +203,7 @@ examples:
                         phys = <&phy_gmii_sel 2>;
                         phy-handle = <&ethphy1_sw>;
                         phy-mode = "rgmii";
-                        ti,dual_emac_pvid = <2>;
+                        ti,dual-emac-pvid = <2>;
                 };
         };
 
index 659b020..daf1321 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Security ID Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 allOf:
   - $ref: "nvmem.yaml#"
index 2e0723a..f7b3ed7 100644 (file)
@@ -4,6 +4,7 @@ Required properties:
 - compatible: should be "amlogic,meson-gxbb-efuse"
 - clocks: phandle to the efuse peripheral clock provided by the
          clock controller.
+- secure-monitor: phandle to the secure-monitor node
 
 = Data cells =
 Are child nodes of eFuse, bindings of which as described in
@@ -16,6 +17,7 @@ Example:
                clocks = <&clkc CLKID_EFUSE>;
                #address-cells = <1>;
                #size-cells = <1>;
+               secure-monitor = <&sm>;
 
                sn: sn@14 {
                        reg = <0x14 0x10>;
@@ -30,6 +32,10 @@ Example:
                };
        };
 
+       sm: secure-monitor {
+               compatible = "amlogic,meson-gxbb-sm";
+       };
+
 = Data consumers =
 Are device nodes which consume nvmem data cells.
 
index fa46670..230d74f 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A31 MIPI D-PHY Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#phy-cells":
diff --git a/Documentation/devicetree/bindings/phy/phy-mmp3-usb.txt b/Documentation/devicetree/bindings/phy/phy-mmp3-usb.txt
new file mode 100644 (file)
index 0000000..7183b91
--- /dev/null
@@ -0,0 +1,13 @@
+Marvell MMP3 USB PHY
+--------------------
+
+Required properties:
+- compatible: must be "marvell,mmp3-usb-phy"
+- #phy-cells: must be 0
+
+Example:
+       usb-phy: usb-phy@d4207000 {
+               compatible = "marvell,mmp3-usb-phy";
+               reg = <0xd4207000 0x40>;
+               #phy-cells = <0>;
+       };
index cd0503b..bfefd09 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Pin Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#gpio-cells":
index eb35b22..bc75bf4 100644 (file)
@@ -5,6 +5,7 @@ which then translates it into a corresponding voltage on a rail
 
 Required Properties:
  - compatible: Should be one of the following
+       * qcom,msm8976-rpmpd: RPM Power domain for the msm8976 family of SoC
        * qcom,msm8996-rpmpd: RPM Power domain for the msm8996 family of SoC
        * qcom,msm8998-rpmpd: RPM Power domain for the msm8998 family of SoC
        * qcom,qcs404-rpmpd: RPM Power domain for the qcs404 family of SoC
index eae2a88..acb41fa 100644 (file)
@@ -12,6 +12,7 @@ Required properties:
       - "renesas,r8a7745-sysc" (RZ/G1E)
       - "renesas,r8a77470-sysc" (RZ/G1C)
       - "renesas,r8a774a1-sysc" (RZ/G2M)
+      - "renesas,r8a774b1-sysc" (RZ/G2N)
       - "renesas,r8a774c0-sysc" (RZ/G2E)
       - "renesas,r8a7779-sysc" (R-Car H1)
       - "renesas,r8a7790-sysc" (R-Car H2)
@@ -21,6 +22,7 @@ Required properties:
       - "renesas,r8a7794-sysc" (R-Car E2)
       - "renesas,r8a7795-sysc" (R-Car H3)
       - "renesas,r8a7796-sysc" (R-Car M3-W)
+      - "renesas,r8a77961-sysc" (R-Car M3-W+)
       - "renesas,r8a77965-sysc" (R-Car M3-N)
       - "renesas,r8a77970-sysc" (R-Car V3M)
       - "renesas,r8a77980-sysc" (R-Car V3H)
index 0ac52f8..4a21fe7 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 PWM Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#pwm-cells":
index 69cae11..95536d8 100644 (file)
@@ -6,7 +6,7 @@ Required properties:
    - "mediatek,mt7622-pwm": found on mt7622 SoC.
    - "mediatek,mt7623-pwm": found on mt7623 SoC.
    - "mediatek,mt7628-pwm": found on mt7628 SoC.
-   - "mediatek,mt7629-pwm", "mediatek,mt7622-pwm": found on mt7629 SoC.
+   - "mediatek,mt7629-pwm": found on mt7629 SoC.
    - "mediatek,mt8516-pwm": found on mt8516 SoC.
  - reg: physical base address and length of the controller's registers.
  - #pwm-cells: must be 2. See pwm.yaml in this directory for a description of
diff --git a/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
new file mode 100644 (file)
index 0000000..4bf2dbf
--- /dev/null
@@ -0,0 +1,65 @@
+NVIDIA Tegra Regulators Coupling
+================================
+
+NVIDIA Tegra SoC's have a mandatory voltage-coupling between regulators.
+Thus on Tegra20 there are 3 coupled regulators and on NVIDIA Tegra30
+there are 2.
+
+Tegra20 voltage coupling
+------------------------
+
+On Tegra20 SoC's there are 3 coupled regulators: CORE, RTC and CPU.
+The CORE and RTC voltages shall be in a range of 170mV from each other
+and they both shall be higher than the CPU voltage by at least 120mV.
+
+Tegra30 voltage coupling
+------------------------
+
+On Tegra30 SoC's there are 2 coupled regulators: CORE and CPU. The CORE
+and CPU voltages shall be in a range of 300mV from each other and CORE
+voltage shall be higher than the CPU by N mV, where N depends on the CPU
+voltage.
+
+Required properties:
+- nvidia,tegra-core-regulator: Boolean property that designates regulator
+  as the "Core domain" voltage regulator.
+- nvidia,tegra-rtc-regulator: Boolean property that designates regulator
+  as the "RTC domain" voltage regulator.
+- nvidia,tegra-cpu-regulator: Boolean property that designates regulator
+  as the "CPU domain" voltage regulator.
+
+Example:
+
+       pmic {
+               regulators {
+                       core_vdd_reg: core {
+                               regulator-name = "vdd_core";
+                               regulator-min-microvolt = <950000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-coupled-with = <&rtc_vdd_reg &cpu_vdd_reg>;
+                               regulator-coupled-max-spread = <170000 550000>;
+
+                               nvidia,tegra-core-regulator;
+                       };
+
+                       rtc_vdd_reg: rtc {
+                               regulator-name = "vdd_rtc";
+                               regulator-min-microvolt = <950000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-coupled-with = <&core_vdd_reg &cpu_vdd_reg>;
+                               regulator-coupled-max-spread = <170000 550000>;
+
+                               nvidia,tegra-rtc-regulator;
+                       };
+
+                       cpu_vdd_reg: cpu {
+                               regulator-name = "vdd_cpu";
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1125000>;
+                               regulator-coupled-with = <&core_vdd_reg &rtc_vdd_reg>;
+                               regulator-coupled-max-spread = <550000 550000>;
+
+                               nvidia,tegra-cpu-regulator;
+                       };
+               };
+       };
index acf18d1..c0d8386 100644 (file)
@@ -50,6 +50,8 @@ properties:
     description: Should contain the WWDG1 watchdog reset interrupt
     maxItems: 1
 
+  wakeup-source: true
+
   mboxes:
     description:
       This property is required only if the rpmsg/virtio functionality is used.
index 26e542e..43e580e 100644 (file)
@@ -4,7 +4,8 @@ The Amlogic Audio ARB is a simple device which enables or
 disables the access of Audio FIFOs to DDR on AXG based SoC.
 
 Required properties:
-- compatible: 'amlogic,meson-axg-audio-arb'
+- compatible: 'amlogic,meson-axg-audio-arb' or
+             'amlogic,meson-sm1-audio-arb'
 - reg: physical base address of the controller and length of memory
        mapped region.
 - clocks: phandle to the fifo peripheral clock provided by the audio
index 00917d8..b3f57d8 100644 (file)
@@ -16,6 +16,7 @@ properties:
       - amlogic,meson8b-reset # Reset Controller on Meson8b and compatible SoCs
       - amlogic,meson-gxbb-reset # Reset Controller on GXBB and compatible SoCs
       - amlogic,meson-axg-reset # Reset Controller on AXG and compatible SoCs
+      - amlogic,meson-a1-reset # Reset Controller on A1 and compatible SoCs
 
   reg:
     maxItems: 1
index 6e5341b..ee59409 100644 (file)
@@ -22,6 +22,6 @@ Example:
        };
 
        &ethernet_switch {
-               resets = <&reset>;
+               resets = <&reset 26>;
                reset-names = "switch";
        };
diff --git a/Documentation/devicetree/bindings/reset/qcom,aoss-reset.txt b/Documentation/devicetree/bindings/reset/qcom,aoss-reset.txt
deleted file mode 100644 (file)
index 510c748..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-Qualcomm AOSS Reset Controller
-======================================
-
-This binding describes a reset-controller found on AOSS-CC (always on subsystem)
-for Qualcomm SDM845 SoCs.
-
-Required properties:
-- compatible:
-       Usage: required
-       Value type: <string>
-       Definition: must be:
-                   "qcom,sdm845-aoss-cc"
-
-- reg:
-       Usage: required
-       Value type: <prop-encoded-array>
-       Definition: must specify the base address and size of the register
-                   space.
-
-- #reset-cells:
-       Usage: required
-       Value type: <uint>
-       Definition: must be 1; cell entry represents the reset index.
-
-Example:
-
-aoss_reset: reset-controller@c2a0000 {
-       compatible = "qcom,sdm845-aoss-cc";
-       reg = <0xc2a0000 0x31000>;
-       #reset-cells = <1>;
-};
-
-Specifying reset lines connected to IP modules
-==============================================
-
-Device nodes that need access to reset lines should
-specify them as a reset phandle in their corresponding node as
-specified in reset.txt.
-
-For list of all valid reset indicies see
-<dt-bindings/reset/qcom,sdm845-aoss.h>
-
-Example:
-
-modem-pil@4080000 {
-       ...
-
-       resets = <&aoss_reset AOSS_CC_MSS_RESTART>;
-       reset-names = "mss_restart";
-
-       ...
-};
diff --git a/Documentation/devicetree/bindings/reset/qcom,aoss-reset.yaml b/Documentation/devicetree/bindings/reset/qcom,aoss-reset.yaml
new file mode 100644 (file)
index 0000000..e2d85a1
--- /dev/null
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/qcom,aoss-reset.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm AOSS Reset Controller
+
+maintainers:
+  - Sibi Sankar <sibis@codeaurora.org>
+
+description:
+  The bindings describe the reset-controller found on AOSS-CC (always on
+  subsystem) for Qualcomm Technologies Inc SoCs.
+
+properties:
+  compatible:
+    oneOf:
+      - description: on SC7180 SoCs the following compatibles must be specified
+        items:
+          - const: "qcom,sc7180-aoss-cc"
+          - const: "qcom,sdm845-aoss-cc"
+
+      - description: on SDM845 SoCs the following compatibles must be specified
+        items:
+          - const: "qcom,sdm845-aoss-cc"
+
+  reg:
+    maxItems: 1
+
+  '#reset-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    aoss_reset: reset-controller@c2a0000 {
+      compatible = "qcom,sdm845-aoss-cc";
+      reg = <0xc2a0000 0x31000>;
+      #reset-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/reset/qcom,pdc-global.txt b/Documentation/devicetree/bindings/reset/qcom,pdc-global.txt
deleted file mode 100644 (file)
index a62a492..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-PDC Global
-======================================
-
-This binding describes a reset-controller found on PDC-Global (Power Domain
-Controller) block for Qualcomm Technologies Inc SDM845 SoCs.
-
-Required properties:
-- compatible:
-       Usage: required
-       Value type: <string>
-       Definition: must be:
-                   "qcom,sdm845-pdc-global"
-
-- reg:
-       Usage: required
-       Value type: <prop-encoded-array>
-       Definition: must specify the base address and size of the register
-                   space.
-
-- #reset-cells:
-       Usage: required
-       Value type: <uint>
-       Definition: must be 1; cell entry represents the reset index.
-
-Example:
-
-pdc_reset: reset-controller@b2e0000 {
-       compatible = "qcom,sdm845-pdc-global";
-       reg = <0xb2e0000 0x20000>;
-       #reset-cells = <1>;
-};
-
-PDC reset clients
-======================================
-
-Device nodes that need access to reset lines should
-specify them as a reset phandle in their corresponding node as
-specified in reset.txt.
-
-For a list of all valid reset indices see
-<dt-bindings/reset/qcom,sdm845-pdc.h>
-
-Example:
-
-modem-pil@4080000 {
-       ...
-
-       resets = <&pdc_reset PDC_MODEM_SYNC_RESET>;
-       reset-names = "pdc_reset";
-
-       ...
-};
diff --git a/Documentation/devicetree/bindings/reset/qcom,pdc-global.yaml b/Documentation/devicetree/bindings/reset/qcom,pdc-global.yaml
new file mode 100644 (file)
index 0000000..d7d8cec
--- /dev/null
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/qcom,pdc-global.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PDC Global
+
+maintainers:
+  - Sibi Sankar <sibis@codeaurora.org>
+
+description:
+  The bindings describes the reset-controller found on PDC-Global (Power Domain
+  Controller) block for Qualcomm Technologies Inc SoCs.
+
+properties:
+  compatible:
+    oneOf:
+      - description: on SC7180 SoCs the following compatibles must be specified
+        items:
+          - const: "qcom,sc7180-pdc-global"
+          - const: "qcom,sdm845-pdc-global"
+
+      - description: on SDM845 SoCs the following compatibles must be specified
+        items:
+          - const: "qcom,sdm845-pdc-global"
+
+  reg:
+    maxItems: 1
+
+  '#reset-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    pdc_reset: reset-controller@b2e0000 {
+      compatible = "qcom,sdm845-pdc-global";
+      reg = <0xb2e0000 0x20000>;
+      #reset-cells = <1>;
+    };
index b03c48a..de7f06c 100644 (file)
@@ -20,6 +20,7 @@ Required properties:
                  - "renesas,r8a7745-rst" (RZ/G1E)
                  - "renesas,r8a77470-rst" (RZ/G1C)
                  - "renesas,r8a774a1-rst" (RZ/G2M)
+                 - "renesas,r8a774b1-rst" (RZ/G2N)
                  - "renesas,r8a774c0-rst" (RZ/G2E)
                  - "renesas,r8a7778-reset-wdt" (R-Car M1A)
                  - "renesas,r8a7779-reset-wdt" (R-Car H1)
@@ -30,6 +31,7 @@ Required properties:
                  - "renesas,r8a7794-rst" (R-Car E2)
                  - "renesas,r8a7795-rst" (R-Car H3)
                  - "renesas,r8a7796-rst" (R-Car M3-W)
+                 - "renesas,r8a77961-rst" (R-Car M3-W+)
                  - "renesas,r8a77965-rst" (R-Car M3-N)
                  - "renesas,r8a77970-rst" (R-Car V3M)
                  - "renesas,r8a77980-rst" (R-Car V3H)
index ea00517..e320a8c 100644 (file)
@@ -130,6 +130,7 @@ this layer. These clocks and resets should be described in each property.
 Required properties:
 - compatible: Should be
     "socionext,uniphier-pro4-usb3-reset" - for Pro4 SoC USB3
+    "socionext,uniphier-pro5-usb3-reset" - for Pro5 SoC USB3
     "socionext,uniphier-pxs2-usb3-reset" - for PXs2 SoC USB3
     "socionext,uniphier-ld20-usb3-reset" - for LD20 SoC USB3
     "socionext,uniphier-pxs3-usb3-reset" - for PXs3 SoC USB3
@@ -141,12 +142,12 @@ Required properties:
 - clocks: A list of phandles to the clock gate for the glue layer.
        According to the clock-names, appropriate clocks are required.
 - clock-names: Should contain
-    "gio", "link" - for Pro4 SoC
+    "gio", "link" - for Pro4 and Pro5 SoCs
     "link"        - for others
 - resets: A list of phandles to the reset control for the glue layer.
        According to the reset-names, appropriate resets are required.
 - reset-names: Should contain
-    "gio", "link" - for Pro4 SoC
+    "gio", "link" - for Pro4 and Pro5 SoCs
     "link"        - for others
 
 Example:
index 46d69c3..478b023 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index d7a57ec..37c2a60 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A31 RTC Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#clock-cells":
index ee9712f..2ecab8e 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 PS2 Host Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 description:
   A20 PS2 is dual role controller (PS2 host and PS2 device). These
index e284e4e..5a33619 100644 (file)
@@ -5,7 +5,7 @@ and power management.
 
 Required properites:
   - reg : Offset and length of the register set of the RCPM block.
-  - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the
+  - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the
        fsl,rcpm-wakeup property.
   - compatible : Must contain a chip-specific RCPM block compatible string
        and (if applicable) may contain a chassis-version RCPM compatible
@@ -20,6 +20,7 @@ Required properites:
        * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm
        * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm
        * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm
+       * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm
 
 All references to "1.0" and "2.0" refer to the QorIQ chassis version to
 which the chip complies.
@@ -27,14 +28,19 @@ Chassis Version             Example Chips
 ---------------                -------------------------------
 1.0                            p4080, p5020, p5040, p2041, p3041
 2.0                            t4240, b4860, b4420
-2.1                            t1040, ls1021
+2.1                            t1040,
+2.1+                           ls1021a, ls1012a, ls1043a, ls1046a
+
+Optional properties:
+ - little-endian : RCPM register block is Little Endian. Without it RCPM
+   will be Big Endian (default case).
 
 Example:
 The RCPM node for T4240:
        rcpm: global-utilities@e2000 {
                compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0";
                reg = <0xe2000 0x1000>;
-               fsl,#rcpm-wakeup-cells = <2>;
+               #fsl,rcpm-wakeup-cells = <2>;
        };
 
 * Freescale RCPM Wakeup Source Device Tree Bindings
@@ -44,7 +50,7 @@ can be used as a wakeup source.
 
   - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR
        register cells. The number of IPPDEXPCR register cells is defined in
-       "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is
+       "#fsl,rcpm-wakeup-cells" in the rcpm node. The first register cell is
        the bit mask that should be set in IPPDEXPCR0, and the second register
        cell is for IPPDEXPCR1, and so on.
 
index f3fa313..616fddc 100644 (file)
@@ -22,6 +22,7 @@ resources.
                    "qcom,rpm-apq8084"
                    "qcom,rpm-msm8916"
                    "qcom,rpm-msm8974"
+                   "qcom,rpm-msm8976"
                    "qcom,rpm-msm8998"
                    "qcom,rpm-sdm660"
                    "qcom,rpm-qcs404"
index 46e27cd..f96511a 100644 (file)
@@ -10,6 +10,12 @@ From RK3368 SoCs, the GRF is divided into two sections,
 
 On RK3328 SoCs, the GRF adds a section for USB2PHYGRF,
 
+ON RK3308 SoC, the GRF is divided into four sections:
+- GRF, used for general non-secure system,
+- SGRF, used for general secure system,
+- DETECTGRF, used for audio codec system,
+- COREGRF, used for pvtm,
+
 Required Properties:
 
 - compatible: GRF should be one of the following:
@@ -19,19 +25,25 @@ Required Properties:
    - "rockchip,rk3188-grf", "syscon": for rk3188
    - "rockchip,rk3228-grf", "syscon": for rk3228
    - "rockchip,rk3288-grf", "syscon": for rk3288
+   - "rockchip,rk3308-grf", "syscon": for rk3308
    - "rockchip,rk3328-grf", "syscon": for rk3328
    - "rockchip,rk3368-grf", "syscon": for rk3368
    - "rockchip,rk3399-grf", "syscon": for rk3399
    - "rockchip,rv1108-grf", "syscon": for rv1108
+- compatible: DETECTGRF should be one of the following:
+   - "rockchip,rk3308-detect-grf", "syscon": for rk3308
+- compatilbe: COREGRF should be one of the following:
+   - "rockchip,rk3308-core-grf", "syscon": for rk3308
 - compatible: PMUGRF should be one of the following:
    - "rockchip,px30-pmugrf", "syscon": for px30
    - "rockchip,rk3368-pmugrf", "syscon": for rk3368
    - "rockchip,rk3399-pmugrf", "syscon": for rk3399
-- compatible: SGRF should be one of the following
+- compatible: SGRF should be one of the following:
    - "rockchip,rk3288-sgrf", "syscon": for rk3288
-- compatible: USB2PHYGRF should be one of the followings
+- compatible: USB2PHYGRF should be one of the following:
+   - "rockchip,px30-usb2phy-grf", "syscon": for px30
    - "rockchip,rk3328-usb2phy-grf", "syscon": for rk3328
-- compatible: USBGRF should be one of the following
+- compatible: USBGRF should be one of the following:
    - "rockchip,rv1108-usbgrf", "syscon": for rv1108
 - reg: physical base address of the controller and length of memory mapped
   region.
index b8f89c7..ea1d2ef 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Codec Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#sound-dai-cells":
index eb39921..112ae00 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 I2S Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#sound-dai-cells":
index 38d4ced..444a432 100644 (file)
@@ -10,7 +10,7 @@ maintainers:
   - Chen-Yu Tsai <wens@csie.org>
   - Liam Girdwood <lgirdwood@gmail.com>
   - Mark Brown <broonie@kernel.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#sound-dai-cells":
index f290eb7..3b76441 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A64 Analog Codec Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 85305b4..9718358 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A23 Analog Codec Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 5e7cc05..55d2826 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A33 Codec Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#sound-dai-cells":
index 6d1329c..8036499 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#address-cells": true
index f36c46d..0565dc4 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   "#address-cells": true
diff --git a/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml
new file mode 100644 (file)
index 0000000..222990f
--- /dev/null
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sram/qcom,ocmem.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs.
+
+maintainers:
+  - Brian Masney <masneyb@onstation.org>
+
+description: |
+  The On Chip Memory (OCMEM) is typically used by the GPU, camera/video, and
+  audio components on some Snapdragon SoCs.
+
+properties:
+  compatible:
+    const: qcom,msm8974-ocmem
+
+  reg:
+    items:
+      - description: Control registers
+      - description: OCMEM address range
+
+  reg-names:
+    items:
+      - const: ctrl
+      - const: mem
+
+  clocks:
+    items:
+      - description: Core clock
+      - description: Interface clock
+
+  clock-names:
+    items:
+      - const: core
+      - const: iface
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+patternProperties:
+  "^.+-sram$":
+    type: object
+    description: A region of reserved memory.
+
+    properties:
+      reg:
+        maxItems: 1
+
+      ranges:
+        maxItems: 1
+
+    required:
+      - reg
+      - ranges
+
+examples:
+  - |
+      #include <dt-bindings/clock/qcom,rpmcc.h>
+      #include <dt-bindings/clock/qcom,mmcc-msm8974.h>
+
+      ocmem: ocmem@fdd00000 {
+        compatible = "qcom,msm8974-ocmem";
+
+        reg = <0xfdd00000 0x2000>,
+              <0xfec00000 0x180000>;
+        reg-names = "ctrl",
+                    "mem";
+
+        clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
+                 <&mmcc OCMEMCX_OCMEMNOC_CLK>;
+        clock-names = "core",
+                      "iface";
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        gmu-sram@0 {
+                reg = <0x0 0x100000>;
+                ranges = <0 0 0xfec00000 0x100000>;
+        };
+      };
diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
new file mode 100644 (file)
index 0000000..f761681
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/amlogic,thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Thermal
+
+maintainers:
+  - Guillaume La Roque <glaroque@baylibre.com>
+
+description: Binding for Amlogic Thermal
+
+properties:
+  compatible:
+      items:
+        - enum:
+            - amlogic,g12a-cpu-thermal
+            - amlogic,g12a-ddr-thermal
+        - const: amlogic,g12a-thermal
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  amlogic,ao-secure:
+    description: phandle to the ao-secure syscon
+    $ref: '/schemas/types.yaml#/definitions/phandle'
+
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - amlogic,ao-secure
+
+examples:
+  - |
+        cpu_temp: temperature-sensor@ff634800 {
+                compatible = "amlogic,g12a-cpu-thermal",
+                             "amlogic,g12a-thermal";
+                reg = <0xff634800 0x50>;
+                interrupts = <0x0 0x24 0x0>;
+                clocks = <&clk 164>;
+                #thermal-sensor-cells = <0>;
+                amlogic,ao-secure = <&sec_AO>;
+        };
+...
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
deleted file mode 100644 (file)
index 673cc18..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-* QCOM SoC Temperature Sensor (TSENS)
-
-Required properties:
-- compatible:
-  Must be one of the following:
-    - "qcom,msm8916-tsens" (MSM8916)
-    - "qcom,msm8974-tsens" (MSM8974)
-    - "qcom,msm8996-tsens" (MSM8996)
-    - "qcom,qcs404-tsens", "qcom,tsens-v1" (QCS404)
-    - "qcom,msm8998-tsens", "qcom,tsens-v2" (MSM8998)
-    - "qcom,sdm845-tsens", "qcom,tsens-v2" (SDM845)
-  The generic "qcom,tsens-v2" property must be used as a fallback for any SoC
-  with version 2 of the TSENS IP. MSM8996 is the only exception because the
-  generic property did not exist when support was added.
-  Similarly, the generic "qcom,tsens-v1" property must be used as a fallback for
-  any SoC with version 1 of the TSENS IP.
-
-- reg: Address range of the thermal registers.
-  New platforms containing v2.x.y of the TSENS IP must specify the SROT and TM
-  register spaces separately, with order being TM before SROT.
-  See Example 2, below.
-
-- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
-- #qcom,sensors: Number of sensors in tsens block
-- Refer to Documentation/devicetree/bindings/nvmem/nvmem.txt to know how to specify
-nvmem cells
-
-Example 1 (legacy support before a fallback tsens-v2 property was introduced):
-tsens: thermal-sensor@900000 {
-               compatible = "qcom,msm8916-tsens";
-               reg = <0x4a8000 0x2000>;
-               nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
-               nvmem-cell-names = "caldata", "calsel";
-               #thermal-sensor-cells = <1>;
-       };
-
-Example 2 (for any platform containing v2 of the TSENS IP):
-tsens0: thermal-sensor@c263000 {
-               compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
-               reg = <0xc263000 0x1ff>, /* TM */
-                       <0xc222000 0x1ff>; /* SROT */
-               #qcom,sensors = <13>;
-               #thermal-sensor-cells = <1>;
-       };
-
-Example 3 (for any platform containing v1 of the TSENS IP):
-tsens: thermal-sensor@4a9000 {
-               compatible = "qcom,qcs404-tsens", "qcom,tsens-v1";
-               reg = <0x004a9000 0x1000>, /* TM */
-                     <0x004a8000 0x1000>; /* SROT */
-               nvmem-cells = <&tsens_caldata>;
-               nvmem-cell-names = "calib";
-               #qcom,sensors = <10>;
-               #thermal-sensor-cells = <1>;
-       };
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
new file mode 100644 (file)
index 0000000..eef13b9
--- /dev/null
@@ -0,0 +1,170 @@
+# SPDX-License-Identifier: (GPL-2.0 OR MIT)
+# Copyright 2019 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/qcom-tsens.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: QCOM SoC Temperature Sensor (TSENS)
+
+maintainers:
+  - Amit Kucheria <amit.kucheria@linaro.org>
+
+description: |
+  QCOM SoCs have TSENS IP to allow temperature measurement. There are currently
+  three distinct major versions of the IP that is supported by a single driver.
+  The IP versions are named v0.1, v1 and v2 in the driver, where v0.1 captures
+  everything before v1 when there was no versioning information.
+
+properties:
+  compatible:
+    oneOf:
+      - description: v0.1 of TSENS
+        items:
+          - enum:
+              - qcom,msm8916-tsens
+              - qcom,msm8974-tsens
+          - const: qcom,tsens-v0_1
+
+      - description: v1 of TSENS
+        items:
+          - enum:
+              - qcom,msm8976-tsens
+              - qcom,qcs404-tsens
+          - const: qcom,tsens-v1
+
+      - description: v2 of TSENS
+        items:
+          - enum:
+              - qcom,msm8996-tsens
+              - qcom,msm8998-tsens
+              - qcom,sdm845-tsens
+          - const: qcom,tsens-v2
+
+  reg:
+    maxItems: 2
+    items:
+      - description: TM registers
+      - description: SROT registers
+
+  nvmem-cells:
+    minItems: 1
+    maxItems: 2
+    description:
+      Reference to an nvmem node for the calibration data
+
+  nvmem-cells-names:
+    minItems: 1
+    maxItems: 2
+    items:
+      - enum:
+        - caldata
+        - calsel
+
+  "#qcom,sensors":
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 1
+      - maximum: 16
+    description:
+      Number of sensors enabled on this platform
+
+  "#thermal-sensor-cells":
+    const: 1
+    description:
+      Number of cells required to uniquely identify the thermal sensors. Since
+      we have multiple sensors this is set to 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,msm8916-tsens
+              - qcom,msm8974-tsens
+              - qcom,msm8976-tsens
+              - qcom,qcs404-tsens
+              - qcom,tsens-v0_1
+              - qcom,tsens-v1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: Combined interrupt if upper or lower threshold crossed
+        interrupt-names:
+          items:
+            - const: uplow
+
+    else:
+      properties:
+        interrupts:
+          items:
+            - description: Combined interrupt if upper or lower threshold crossed
+            - description: Interrupt if critical threshold crossed
+        interrupt-names:
+          items:
+            - const: uplow
+            - const: critical
+
+required:
+  - compatible
+  - reg
+  - "#qcom,sensors"
+  - interrupts
+  - interrupt-names
+  - "#thermal-sensor-cells"
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    // Example 1 (legacy: for pre v1 IP):
+    tsens1: thermal-sensor@900000 {
+           compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1";
+           reg = <0x4a9000 0x1000>, /* TM */
+                 <0x4a8000 0x1000>; /* SROT */
+
+           nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
+           nvmem-cell-names = "caldata", "calsel";
+
+           interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+           interrupt-names = "uplow";
+
+           #qcom,sensors = <5>;
+           #thermal-sensor-cells = <1>;
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    // Example 2 (for any platform containing v1 of the TSENS IP):
+    tsens2: thermal-sensor@4a9000 {
+          compatible = "qcom,qcs404-tsens", "qcom,tsens-v1";
+          reg = <0x004a9000 0x1000>, /* TM */
+                <0x004a8000 0x1000>; /* SROT */
+
+          nvmem-cells = <&tsens_caldata>;
+          nvmem-cell-names = "calib";
+
+          interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>;
+          interrupt-names = "uplow";
+
+          #qcom,sensors = <10>;
+          #thermal-sensor-cells = <1>;
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    // Example 3 (for any platform containing v2 of the TSENS IP):
+    tsens3: thermal-sensor@c263000 {
+           compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
+           reg = <0xc263000 0x1ff>,
+                 <0xc222000 0x1ff>;
+
+           interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+                        <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
+           interrupt-names = "uplow", "critical";
+
+           #qcom,sensors = <13>;
+           #thermal-sensor-cells = <1>;
+    };
+...
index b6ab60f..12c740b 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
 - compatible           : "renesas,<soctype>-thermal",
                          Examples with soctypes are:
                            - "renesas,r8a774a1-thermal" (RZ/G2M)
+                           - "renesas,r8a774b1-thermal" (RZ/G2N)
                            - "renesas,r8a7795-thermal" (R-Car H3)
                            - "renesas,r8a7796-thermal" (R-Car M3-W)
                            - "renesas,r8a77965-thermal" (R-Car M3-N)
index 20adc1c..23e989e 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 Timer Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index dfa0c41..40fc4bc 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A13 High-Speed Timer Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index 74c3ead..0d25648 100644 (file)
@@ -21,6 +21,7 @@ Required properties:
        * "mediatek,mt6577-timer" for MT6577 and all above compatible timers (GPT)
 
        For those SoCs that use SYST
+       * "mediatek,mt8183-timer" for MT8183 compatible timers (SYST)
        * "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
        * "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
 
index 13ad074..9dff7e5 100644 (file)
@@ -10,6 +10,7 @@ Required Properties:
 
   - compatible: must contain one or more of the following:
     - "renesas,tmu-r8a7740" for the r8a7740 TMU
+    - "renesas,tmu-r8a774a1" for the r8a774A1 TMU
     - "renesas,tmu-r8a774c0" for the r8a774C0 TMU
     - "renesas,tmu-r8a7778" for the r8a7778 TMU
     - "renesas,tmu-r8a7779" for the r8a7779 TMU
index 0af70fc..d9207bf 100644 (file)
@@ -8,7 +8,7 @@ title: Allwinner A10 mUSB OTG Controller Device Tree Bindings
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index fd6fa07..6046f45 100644 (file)
@@ -707,6 +707,8 @@ patternProperties:
     description: Ortus Technology Co., Ltd.
   "^osddisplays,.*":
     description: OSD Displays
+  "^overkiz,.*":
+    description: Overkiz SAS
   "^ovti,.*":
     description: OmniVision Technologies
   "^oxsemi,.*":
@@ -990,6 +992,8 @@ patternProperties:
     description: Ubiquiti Networks
   "^udoo,.*":
     description: Udoo
+  "^ugoos,.*":
+    description: Ugoos Industrial Co., Ltd.
   "^uniwest,.*":
     description: United Western Technologies Corp (UniWest)
   "^upisemi,.*":
index 3a54f58..e8f2263 100644 (file)
@@ -11,7 +11,7 @@ allOf:
 
 maintainers:
   - Chen-Yu Tsai <wens@csie.org>
-  - Maxime Ripard <maxime.ripard@bootlin.com>
+  - Maxime Ripard <mripard@kernel.org>
 
 properties:
   compatible:
index fab2c9b..b40b1f8 100644 (file)
@@ -725,24 +725,10 @@ method, the sys I/F structure will be built like this::
     |---temp1_input:           37000
     |---temp1_crit:            100000
 
-4. Event Notification
+4. Export Symbol APIs
 =====================
 
-The framework includes a simple notification mechanism, in the form of a
-netlink event. Netlink socket initialization is done during the _init_
-of the framework. Drivers which intend to use the notification mechanism
-just need to call thermal_generate_netlink_event() with two arguments viz
-(originator, event). The originator is a pointer to struct thermal_zone_device
-from where the event has been originated. An integer which represents the
-thermal zone device will be used in the message to identify the zone. The
-event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
-THERMAL_DEV_FAULT}. Notification can be sent when the current temperature
-crosses any of the configured thresholds.
-
-5. Export Symbol APIs
-=====================
-
-5.1. get_tz_trend
+4.1. get_tz_trend
 -----------------
 
 This function returns the trend of a thermal zone, i.e the rate of change
@@ -751,14 +737,14 @@ are supposed to implement the callback. If they don't, the thermal
 framework calculated the trend by comparing the previous and the current
 temperature values.
 
-5.2. get_thermal_instance
+4.2. get_thermal_instance
 -------------------------
 
 This function returns the thermal_instance corresponding to a given
 {thermal_zone, cooling_device, trip_point} combination. Returns NULL
 if such an instance does not exist.
 
-5.3. thermal_notify_framework
+4.3. thermal_notify_framework
 -----------------------------
 
 This function handles the trip events from sensor drivers. It starts
@@ -768,14 +754,14 @@ and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
 The throttling policy is based on the configured platform data; if no
 platform data is provided, this uses the step_wise throttling policy.
 
-5.4. thermal_cdev_update
+4.4. thermal_cdev_update
 ------------------------
 
 This function serves as an arbitrator to set the state of a cooling
 device. It sets the cooling device to the deepest cooling state if
 possible.
 
-6. thermal_emergency_poweroff
+5. thermal_emergency_poweroff
 =============================
 
 On an event of critical trip temperature crossing. Thermal framework
index b0c0853..db6d39c 100644 (file)
@@ -24,11 +24,11 @@ Here is the main features of EROFS:
  - Metadata & data could be mixed by design;
 
  - 2 inode versions for different requirements:
-                          v1            v2
+                          compact (v1)  extended (v2)
    Inode metadata size:   32 bytes      64 bytes
    Max file size:         4 GB          16 EB (also limited by max. vol size)
    Max uids/gids:         65536         4294967296
-   File creation time:    no            yes (64 + 32-bit timestamp)
+   File change time:      no            yes (64 + 32-bit timestamp)
    Max hardlinks:         65536         4294967296
    Metadata reserved:     4 bytes       14 bytes
 
@@ -39,7 +39,7 @@ Here is the main features of EROFS:
  - Support POSIX.1e ACLs by using xattrs;
 
  - Support transparent file compression as an option:
-   LZ4 algorithm with 4 KB fixed-output compression for high performance;
+   LZ4 algorithm with 4 KB fixed-sized output compression for high performance.
 
 The following git tree provides the file system user-space tools under
 development (ex, formatting tool mkfs.erofs):
@@ -85,7 +85,7 @@ All data areas should be aligned with the block size, but metadata areas
 may not. All metadatas can be now observed in two different spaces (views):
  1. Inode metadata space
     Each valid inode should be aligned with an inode slot, which is a fixed
-    value (32 bytes) and designed to be kept in line with v1 inode size.
+    value (32 bytes) and designed to be kept in line with compact inode size.
 
     Each inode can be directly found with the following formula:
          inode offset = meta_blkaddr * block_size + 32 * nid
@@ -117,10 +117,10 @@ may not. All metadatas can be now observed in two different spaces (views):
                                                        |-> aligned with 4B
 
     Inode could be 32 or 64 bytes, which can be distinguished from a common
-    field which all inode versions have -- i_advise:
+    field which all inode versions have -- i_format:
 
         __________________               __________________
-       |     i_advise     |             |     i_advise     |
+       |     i_format     |             |     i_format     |
        |__________________|             |__________________|
        |        ...       |             |        ...       |
        |                  |             |                  |
@@ -129,12 +129,13 @@ may not. All metadatas can be now observed in two different spaces (views):
                                         |__________________| 64 bytes
 
     Xattrs, extents, data inline are followed by the corresponding inode with
-    proper alignes, and they could be optional for different data mappings,
-    _currently_ there are totally 3 valid data mappings supported:
+    proper alignment, and they could be optional for different data mappings.
+    _currently_ total 4 valid data mappings are supported:
 
-     1) flat file data without data inline (no extent);
-     2) fixed-output size data compression (must have extents);
-     3) flat file data with tail-end data inline (no extent);
+     0  flat file data without data inline (no extent);
+     1  fixed-sized output data compression (with non-compacted indexes);
+     2  flat file data with tail packing data inline (no extent);
+     3  fixed-sized output data compression (with compacted indexes, v5.3+).
 
     The size of the optional xattrs is indicated by i_xattr_count in inode
     header. Large xattrs or xattrs shared by many different files can be
@@ -182,8 +183,8 @@ introduce another on-disk field at all.
 
 Compression
 -----------
-Currently, EROFS supports 4KB fixed-output clustersize transparent file
-compression, as illustrated below:
+Currently, EROFS supports 4KB fixed-sized output transparent file compression,
+as illustrated below:
 
          |---- Variant-Length Extent ----|-------- VLE --------|----- VLE -----
          clusterofs                      clusterofs            clusterofs
similarity index 99%
rename from Documentation/filesystems/overlayfs.txt
rename to Documentation/filesystems/overlayfs.rst
index 845d689..e443be7 100644 (file)
@@ -1,3 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
 Written by: Neil Brown
 Please see MAINTAINERS file for where to send questions.
 
@@ -181,7 +183,7 @@ Kernel config options:
     worried about backward compatibility with kernels that have the redirect_dir
     feature and follow redirects even if turned off.
 
-Module options (can also be changed through /sys/module/overlay/parameters/*):
+Module options (can also be changed through /sys/module/overlay/parameters/):
 
 - "redirect_dir=BOOL":
     See OVERLAY_FS_REDIRECT_DIR kernel config option above.
@@ -263,7 +265,7 @@ top, lower2 the middle and lower3 the bottom layer.
 
 
 Metadata only copy up
---------------------
+---------------------
 
 When metadata only copy up feature is enabled, overlayfs will only copy
 up metadata (as opposed to whole file), when a metadata specific operation
@@ -286,10 +288,10 @@ pointed by REDIRECT. This should not be possible on local system as setting
 "trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible
 for untrusted layers like from a pen drive.
 
-Note: redirect_dir={off|nofollow|follow(*)} conflicts with metacopy=on, and
+Note: redirect_dir={off|nofollow|follow[*]} conflicts with metacopy=on, and
 results in an error.
 
-(*) redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
+[*] redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
 given.
 
 Sharing and copying layers
index ada573b..edb296c 100644 (file)
@@ -988,7 +988,7 @@ Similarly, if you need to calculate the size of some structure member, use
 
 .. code-block:: c
 
-       #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+       #define sizeof_field(t, f) (sizeof(((t*)0)->f))
 
 There are also min() and max() macros that do strict type checking if you
 need them.  Feel free to peruse that header file to see what else is already
index 201f80c..df129f5 100644 (file)
@@ -29,7 +29,7 @@ smartpqi specific entries in /sys
   smartpqi host attributes:
   -------------------------
   /sys/class/scsi_host/host*/rescan
-  /sys/class/scsi_host/host*/version
+  /sys/class/scsi_host/host*/driver_version
 
   The host rescan attribute is a write only attribute. Writing to this
   attribute will trigger the driver to scan for new, changed, or removed
index 8995d2d..8725f2b 100644 (file)
@@ -1005,7 +1005,7 @@ struttura, usate
 
 .. code-block:: c
 
-       #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+       #define sizeof_field(t, f) (sizeof(((t*)0)->f))
 
 Ci sono anche le macro min() e max() che, se vi serve, effettuano un controllo
 rigido sui tipi.  Sentitevi liberi di leggere attentamente questo file
index 4f62373..eae10bc 100644 (file)
@@ -826,7 +826,7 @@ inline gcc 也可以自动使其内联。而且其他用户可能会要求移除
 
 .. code-block:: c
 
-       #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+       #define sizeof_field(t, f) (sizeof(((t*)0)->f))
 
 还有可以做严格的类型检查的 min() 和 max() 宏,如果你需要可以使用它们。你可以
 自己看看那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应
index 49183ad..ebb37b3 100644 (file)
@@ -5,7 +5,7 @@ The Definitive KVM (Kernel-based Virtual Machine) API Documentation
 ----------------------
 
 The kvm API is a set of ioctls that are issued to control various aspects
-of a virtual machine.  The ioctls belong to three classes:
+of a virtual machine.  The ioctls belong to the following classes:
 
  - System ioctls: These query and set global attributes which affect the
    whole kvm subsystem.  In addition a system ioctl is used to create
@@ -4149,6 +4149,24 @@ Valid values for 'action':
 #define KVM_PMU_EVENT_ALLOW 0
 #define KVM_PMU_EVENT_DENY 1
 
+4.121 KVM_PPC_SVM_OFF
+
+Capability: basic
+Architectures: powerpc
+Type: vm ioctl
+Parameters: none
+Returns: 0 on successful completion,
+Errors:
+  EINVAL:    if ultravisor failed to terminate the secure guest
+  ENOMEM:    if hypervisor failed to allocate new radix page tables for guest
+
+This ioctl is used to turn off the secure mode of the guest or transition
+the guest from secure mode to normal mode. This is invoked when the guest
+is reset. This has no effect if called for a normal guest.
+
+This ioctl issues an ultravisor call to terminate the secure guest,
+unpins the VPA pages and releases all the device pages that are used to
+track the secure pages by hypervisor.
 
 5. The kvm_run structure
 ------------------------
index 061d59a..a049abc 100644 (file)
@@ -862,7 +862,6 @@ S:  Maintained
 F:     drivers/i2c/busses/i2c-amd-mp2*
 
 AMD POWERPLAY
-M:     Rex Zhu <rex.zhu@amd.com>
 M:     Evan Quan <evan.quan@amd.com>
 L:     amd-gfx@lists.freedesktop.org
 S:     Supported
@@ -1585,8 +1584,8 @@ S:        Maintained
 F:     arch/arm/mach-cns3xxx/
 
 ARM/CAVIUM THUNDER NETWORK DRIVER
-M:     Sunil Goutham <sgoutham@cavium.com>
-M:     Robert Richter <rric@kernel.org>
+M:     Sunil Goutham <sgoutham@marvell.com>
+M:     Robert Richter <rrichter@marvell.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 F:     drivers/net/ethernet/cavium/thunder/
@@ -1934,7 +1933,7 @@ F:        arch/arm/boot/dts/dove*
 F:     arch/arm/boot/dts/orion5x*
 T:     git git://git.infradead.org/linux-mvebu.git
 
-ARM/Marvell Kirkwood and Armada 370, 375, 38x, 39x, XP, 3700, 7K/8K SOC support
+ARM/Marvell Kirkwood and Armada 370, 375, 38x, 39x, XP, 3700, 7K/8K, CN9130 SOC support
 M:     Jason Cooper <jason@lakedaemon.net>
 M:     Andrew Lunn <andrew@lunn.ch>
 M:     Gregory Clement <gregory.clement@bootlin.com>
@@ -1946,6 +1945,7 @@ F:        arch/arm/boot/dts/kirkwood*
 F:     arch/arm/configs/mvebu_*_defconfig
 F:     arch/arm/mach-mvebu/
 F:     arch/arm64/boot/dts/marvell/armada*
+F:     arch/arm64/boot/dts/marvell/cn913*
 F:     drivers/cpufreq/armada-37xx-cpufreq.c
 F:     drivers/cpufreq/armada-8k-cpufreq.c
 F:     drivers/cpufreq/mvebu-cpufreq.c
@@ -2140,6 +2140,7 @@ S:        Maintained
 
 ARM/QUALCOMM SUPPORT
 M:     Andy Gross <agross@kernel.org>
+M:     Bjorn Andersson <bjorn.andersson@linaro.org>
 L:     linux-arm-msm@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/soc/qcom/
@@ -2200,6 +2201,7 @@ F:        Documentation/devicetree/bindings/timer/rda,8810pl-timer.txt
 ARM/REALTEK ARCHITECTURE
 M:     Andreas Färber <afaerber@suse.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-realtek-soc@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm64/boot/dts/realtek/
 F:     Documentation/devicetree/bindings/arm/realtek.yaml
@@ -2270,6 +2272,7 @@ F:        drivers/*/*s3c64xx*
 F:     drivers/*/*s5pv210*
 F:     drivers/memory/samsung/
 F:     drivers/soc/samsung/
+F:     drivers/tty/serial/samsung*
 F:     include/linux/soc/samsung/
 F:     Documentation/arm/samsung/
 F:     Documentation/devicetree/bindings/arm/samsung/
@@ -3226,8 +3229,7 @@ N:        kona
 F:     arch/arm/mach-bcm/
 
 BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
-M:     Eric Anholt <eric@anholt.net>
-M:     Stefan Wahren <wahrenst@gmx.net>
+M:     Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
 L:     bcm-kernel-feedback-list@broadcom.com
 L:     linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -3740,9 +3742,8 @@ S:        Maintained
 F:     drivers/net/wireless/ath/carl9170/
 
 CAVIUM I2C DRIVER
-M:     Jan Glauber <jglauber@cavium.com>
-M:     David Daney <david.daney@cavium.com>
-W:     http://www.cavium.com
+M:     Robert Richter <rrichter@marvell.com>
+W:     http://www.marvell.com
 S:     Supported
 F:     drivers/i2c/busses/i2c-octeon*
 F:     drivers/i2c/busses/i2c-thunderx*
@@ -3752,27 +3753,25 @@ M:      Derek Chickles <dchickles@marvell.com>
 M:     Satanand Burla <sburla@marvell.com>
 M:     Felix Manlunas <fmanlunas@marvell.com>
 L:     netdev@vger.kernel.org
-W:     http://www.cavium.com
+W:     http://www.marvell.com
 S:     Supported
 F:     drivers/net/ethernet/cavium/liquidio/
 
 CAVIUM MMC DRIVER
-M:     Jan Glauber <jglauber@cavium.com>
-M:     David Daney <david.daney@cavium.com>
-M:     Steven J. Hill <Steven.Hill@cavium.com>
-W:     http://www.cavium.com
+M:     Robert Richter <rrichter@marvell.com>
+W:     http://www.marvell.com
 S:     Supported
 F:     drivers/mmc/host/cavium*
 
 CAVIUM OCTEON-TX CRYPTO DRIVER
-M:     George Cherian <george.cherian@cavium.com>
+M:     George Cherian <gcherian@marvell.com>
 L:     linux-crypto@vger.kernel.org
-W:     http://www.cavium.com
+W:     http://www.marvell.com
 S:     Supported
 F:     drivers/crypto/cavium/cpt/
 
 CAVIUM THUNDERX2 ARM64 SOC
-M:     Robert Richter <rrichter@cavium.com>
+M:     Robert Richter <rrichter@marvell.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm64/boot/dts/cavium/thunder2-99xx*
@@ -4972,6 +4971,7 @@ F:        include/linux/dma-buf*
 F:     include/linux/reservation.h
 F:     include/linux/*fence.h
 F:     Documentation/driver-api/dma-buf.rst
+K:     dma_(buf|fence|resv)
 T:     git git://anongit.freedesktop.org/drm/drm-misc
 
 DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
@@ -5000,6 +5000,14 @@ F:       include/linux/dma-direct.h
 F:     include/linux/dma-mapping.h
 F:     include/linux/dma-noncoherent.h
 
+DMC FREQUENCY DRIVER FOR SAMSUNG EXYNOS5422
+M:     Lukasz Luba <lukasz.luba@arm.com>
+L:     linux-pm@vger.kernel.org
+L:     linux-samsung-soc@vger.kernel.org
+S:     Maintained
+F:     drivers/memory/samsung/exynos5422-dmc.c
+F:     Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
+
 DME1737 HARDWARE MONITOR DRIVER
 M:     Juerg Haefliger <juergh@gmail.com>
 L:     linux-hwmon@vger.kernel.org
@@ -5882,15 +5890,14 @@ F:      drivers/edac/highbank*
 
 EDAC-CAVIUM OCTEON
 M:     Ralf Baechle <ralf@linux-mips.org>
-M:     David Daney <david.daney@cavium.com>
+M:     Robert Richter <rrichter@marvell.com>
 L:     linux-edac@vger.kernel.org
 L:     linux-mips@vger.kernel.org
 S:     Supported
 F:     drivers/edac/octeon_edac*
 
 EDAC-CAVIUM THUNDERX
-M:     David Daney <david.daney@cavium.com>
-M:     Jan Glauber <jglauber@cavium.com>
+M:     Robert Richter <rrichter@marvell.com>
 L:     linux-edac@vger.kernel.org
 S:     Supported
 F:     drivers/edac/thunderx_edac*
@@ -8759,6 +8766,7 @@ ISCSI
 M:     Lee Duncan <lduncan@suse.com>
 M:     Chris Leech <cleech@redhat.com>
 L:     open-iscsi@googlegroups.com
+L:     linux-scsi@vger.kernel.org
 W:     www.open-iscsi.com
 S:     Maintained
 F:     drivers/scsi/*iscsi*
@@ -10101,6 +10109,15 @@ W:     https://linuxtv.org
 S:     Maintained
 F:     drivers/media/radio/radio-maxiradio*
 
+MCAN MMIO DEVICE DRIVER
+M:     Sriram Dash <sriram.dash@samsung.com>
+L:     linux-can@vger.kernel.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/net/can/m_can.txt
+F:     drivers/net/can/m_can/m_can.c
+F:     drivers/net/can/m_can/m_can.h
+F:     drivers/net/can/m_can/m_can_platform.c
+
 MCP4018 AND MCP4531 MICROCHIP DIGITAL POTENTIOMETER DRIVERS
 M:     Peter Rosin <peda@axentia.se>
 L:     linux-iio@vger.kernel.org
@@ -11059,9 +11076,18 @@ F:     drivers/media/radio/radio-miropcm20*
 MMP SUPPORT
 R:     Lubomir Rintel <lkundrak@v3.sk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lkundrak/linux-mmp.git
 S:     Odd Fixes
 F:     arch/arm/boot/dts/mmp*
 F:     arch/arm/mach-mmp/
+F:     linux/soc/mmp/
+
+MMP USB PHY DRIVERS
+R:     Lubomir Rintel <lkundrak@v3.sk>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     drivers/phy/marvell/phy-mmp3-usb.c
+F:     drivers/phy/marvell/phy-pxa-usb.c
 
 MMU GATHER AND TLB INVALIDATION
 M:     Will Deacon <will@kernel.org>
@@ -11908,6 +11934,8 @@ F:      arch/arm/boot/dts/*am3*
 F:     arch/arm/boot/dts/*am4*
 F:     arch/arm/boot/dts/*am5*
 F:     arch/arm/boot/dts/*dra7*
+F:     arch/arm/boot/dts/logicpd-som-lv*
+F:     arch/arm/boot/dts/logicpd-torpedo*
 
 OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
 L:     linux-omap@vger.kernel.org
@@ -12367,7 +12395,7 @@ L:      linux-unionfs@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git
 S:     Supported
 F:     fs/overlayfs/
-F:     Documentation/filesystems/overlayfs.txt
+F:     Documentation/filesystems/overlayfs.rst
 
 P54 WIRELESS DRIVER
 M:     Christian Lamparter <chunkeey@googlemail.com>
@@ -12778,7 +12806,7 @@ F:      Documentation/devicetree/bindings/pci/axis,artpec*
 F:     drivers/pci/controller/dwc/*artpec*
 
 PCIE DRIVER FOR CAVIUM THUNDERX
-M:     David Daney <david.daney@cavium.com>
+M:     Robert Richter <rrichter@marvell.com>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
@@ -13688,6 +13716,7 @@ L:      linux-pm@vger.kernel.org
 L:     linux-arm-msm@vger.kernel.org
 S:     Maintained
 F:     drivers/thermal/qcom/
+F:     Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
 
 QUALCOMM VENUS VIDEO ACCELERATOR DRIVER
 M:     Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -13750,7 +13779,7 @@ F:      drivers/media/radio/radio-tea5777.c
 RADOS BLOCK DEVICE (RBD)
 M:     Ilya Dryomov <idryomov@gmail.com>
 M:     Sage Weil <sage@redhat.com>
-M:     Alex Elder <elder@kernel.org>
+R:     Dongsheng Yang <dongsheng.yang@easystack.cn>
 L:     ceph-devel@vger.kernel.org
 W:     http://ceph.com/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
@@ -14027,6 +14056,7 @@ F:      include/dt-bindings/reset/
 F:     include/linux/reset.h
 F:     include/linux/reset/
 F:     include/linux/reset-controller.h
+K:      \b(?:devm_|of_)?reset_control(?:ler_[a-z]+|_[a-z_]+)?\b
 
 RESTARTABLE SEQUENCES SUPPORT
 M:     Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
@@ -16286,12 +16316,10 @@ F:    drivers/media/radio/radio-raremono.c
 
 THERMAL
 M:     Zhang Rui <rui.zhang@intel.com>
-M:     Eduardo Valentin <edubezval@gmail.com>
-R:     Daniel Lezcano <daniel.lezcano@linaro.org>
+M:     Daniel Lezcano <daniel.lezcano@linaro.org>
 R:     Amit Kucheria <amit.kucheria@verdurent.com>
 L:     linux-pm@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git
 Q:     https://patchwork.kernel.org/project/linux-pm/list/
 S:     Supported
 F:     drivers/thermal/
@@ -16310,6 +16338,15 @@ F:     Documentation/driver-api/thermal/cpu-cooling-api.rst
 F:     drivers/thermal/cpu_cooling.c
 F:     include/linux/cpu_cooling.h
 
+THERMAL DRIVER FOR AMLOGIC SOCS
+M:     Guillaume La Roque <glaroque@baylibre.com>
+L:     linux-pm@vger.kernel.org
+L:     linux-amlogic@lists.infradead.org
+W:     http://linux-meson.com/
+S:     Supported
+F:     drivers/thermal/amlogic_thermal.c
+F:     Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
+
 THINKPAD ACPI EXTRAS DRIVER
 M:     Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
 L:     ibm-acpi-devel@lists.sourceforge.net
@@ -16340,7 +16377,7 @@ S:      Maintained
 F:     drivers/net/thunderbolt.c
 
 THUNDERX GPIO DRIVER
-M:     David Daney <david.daney@cavium.com>
+M:     Robert Richter <rrichter@marvell.com>
 S:     Maintained
 F:     drivers/gpio/gpio-thunderx.c
 
@@ -18111,6 +18148,14 @@ M:     Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
 S:     Maintained
 F:     drivers/net/ethernet/xilinx/xilinx_axienet*
 
+XILINX CAN DRIVER
+M:     Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
+R:     Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
+L:     linux-can@vger.kernel.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/net/can/xilinx_can.txt
+F:     drivers/net/can/xilinx_can.c
+
 XILINX UARTLITE SERIAL DRIVER
 M:     Peter Korsgaard <jacmet@sunsite.dk>
 L:     linux-serial@vger.kernel.org
@@ -18145,10 +18190,9 @@ S:     Supported
 F:     drivers/char/xillybus/
 
 XLP9XX I2C DRIVER
-M:     George Cherian <george.cherian@cavium.com>
-M:     Jan Glauber <jglauber@cavium.com>
+M:     George Cherian <gcherian@marvell.com>
 L:     linux-i2c@vger.kernel.org
-W:     http://www.cavium.com
+W:     http://www.marvell.com
 S:     Supported
 F:     Documentation/devicetree/bindings/i2c/i2c-xlp9xx.txt
 F:     drivers/i2c/busses/i2c-xlp9xx.c
index 999a197..f900c23 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
-PATCHLEVEL = 4
+PATCHLEVEL = 5
 SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = -rc2
 NAME = Kleptomaniac Octopus
 
 # *DOCUMENTATION*
index 7b861fe..48b5e10 100644 (file)
@@ -72,11 +72,11 @@ config KPROBES
          If in doubt, say "N".
 
 config JUMP_LABEL
-       bool "Optimize very unlikely/likely branches"
-       depends on HAVE_ARCH_JUMP_LABEL
-       depends on CC_HAS_ASM_GOTO
-       help
-         This option enables a transparent branch optimization that
+       bool "Optimize very unlikely/likely branches"
+       depends on HAVE_ARCH_JUMP_LABEL
+       depends on CC_HAS_ASM_GOTO
+       help
+        This option enables a transparent branch optimization that
         makes certain almost-always-true or almost-always-false branch
         conditions even cheaper to execute within the kernel.
 
@@ -84,7 +84,7 @@ config JUMP_LABEL
         scheduler functionality, networking code and KVM have such
         branches and include support for this optimization technique.
 
-         If it is detected that the compiler has support for "asm goto",
+        If it is detected that the compiler has support for "asm goto",
         the kernel will compile such branches with just a nop
         instruction. When the condition flag is toggled to true, the
         nop will be converted to a jump instruction to execute the
@@ -151,8 +151,8 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS
          information on the topic of unaligned memory accesses.
 
 config ARCH_USE_BUILTIN_BSWAP
-       bool
-       help
+       bool
+       help
         Modern versions of GCC (since 4.4) have builtin functions
         for handling byte-swapping. Using these, instead of the old
         inline assembler that the architecture code provides in the
@@ -221,10 +221,10 @@ config HAVE_DMA_CONTIGUOUS
        bool
 
 config GENERIC_SMP_IDLE_THREAD
-       bool
+       bool
 
 config GENERIC_IDLE_POLL_SETUP
-       bool
+       bool
 
 config ARCH_HAS_FORTIFY_SOURCE
        bool
@@ -257,7 +257,7 @@ config ARCH_HAS_UNCACHED_SEGMENT
 
 # Select if arch init_task must go in the __init_task_data section
 config ARCH_TASK_STRUCT_ON_STACK
-       bool
+       bool
 
 # Select if arch has its private alloc_task_struct() function
 config ARCH_TASK_STRUCT_ALLOCATOR
index 889b5d3..7ee144f 100644 (file)
@@ -73,7 +73,6 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
 #define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
 #define pmd_page(pmd)          (pfn_to_page(pmd_val(pmd) >> 32))
-#define pgd_page(pgd)          (pfn_to_page(pgd_val(pgd) >> 32))
 #define pte_pfn(pte)           (pte_val(pte) >> 32)
 
 #define mk_pte(page, pgprot)                                                \
index eb91f1e..a1a29f6 100644 (file)
@@ -27,9 +27,9 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 }
 
 static inline void
-pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
-       pgd_set(pgd, pmd);
+       pud_set(pud, pmd);
 }
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
index 065b57f..299791c 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _ALPHA_PGTABLE_H
 #define _ALPHA_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 /*
  * This file contains the functions and defines necessary to modify and use
@@ -226,8 +226,8 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 { pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
 
-extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
+extern inline void pud_set(pud_t * pudp, pmd_t * pmdp)
+{ pud_val(*pudp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
 
 
 extern inline unsigned long
@@ -238,11 +238,11 @@ pmd_page_vaddr(pmd_t pmd)
 
 #ifndef CONFIG_DISCONTIGMEM
 #define pmd_page(pmd)  (mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32))
-#define pgd_page(pgd)  (mem_map + ((pgd_val(pgd) & _PFN_MASK) >> 32))
+#define pud_page(pud)  (mem_map + ((pud_val(pud) & _PFN_MASK) >> 32))
 #endif
 
-extern inline unsigned long pgd_page_vaddr(pgd_t pgd)
-{ return PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
+extern inline unsigned long pud_page_vaddr(pud_t pgd)
+{ return PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
 
 extern inline int pte_none(pte_t pte)          { return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)       { return pte_val(pte) & _PAGE_VALID; }
@@ -256,10 +256,10 @@ extern inline int pmd_bad(pmd_t pmd)              { return (pmd_val(pmd) & ~_PFN_MASK) != _P
 extern inline int pmd_present(pmd_t pmd)       { return pmd_val(pmd) & _PAGE_VALID; }
 extern inline void pmd_clear(pmd_t * pmdp)     { pmd_val(*pmdp) = 0; }
 
-extern inline int pgd_none(pgd_t pgd)          { return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd)           { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE; }
-extern inline int pgd_present(pgd_t pgd)       { return pgd_val(pgd) & _PAGE_VALID; }
-extern inline void pgd_clear(pgd_t * pgdp)     { pgd_val(*pgdp) = 0; }
+extern inline int pud_none(pud_t pud)          { return !pud_val(pud); }
+extern inline int pud_bad(pud_t pud)           { return (pud_val(pud) & ~_PFN_MASK) != _PAGE_TABLE; }
+extern inline int pud_present(pud_t pud)       { return pud_val(pud) & _PAGE_VALID; }
+extern inline void pud_clear(pud_t * pudp)     { pud_val(*pudp) = 0; }
 
 /*
  * The following only work if pte_present() is true.
@@ -301,9 +301,9 @@ extern inline pte_t pte_mkspecial(pte_t pte)        { return pte; }
  */
 
 /* Find an entry in the second-level page table.. */
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+extern inline pmd_t * pmd_offset(pud_t * dir, unsigned long address)
 {
-       pmd_t *ret = (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+       pmd_t *ret = (pmd_t *) pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
        smp_read_barrier_depends(); /* see above */
        return ret;
 }
index e2cbec3..12e218d 100644 (file)
@@ -146,6 +146,8 @@ callback_init(void * kernel_end)
 {
        struct crb_struct * crb;
        pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pmd;
        void *two_pages;
 
@@ -184,8 +186,10 @@ callback_init(void * kernel_end)
        memset(two_pages, 0, 2*PAGE_SIZE);
 
        pgd = pgd_offset_k(VMALLOC_START);
-       pgd_set(pgd, (pmd_t *)two_pages);
-       pmd = pmd_offset(pgd, VMALLOC_START);
+       p4d = p4d_offset(pgd, VMALLOC_START);
+       pud = pud_offset(p4d, VMALLOC_START);
+       pud_set(pud, (pmd_t *)two_pages);
+       pmd = pmd_offset(pud, VMALLOC_START);
        pmd_set(pmd, (pte_t *)(two_pages + PAGE_SIZE));
 
        if (alpha_using_srm) {
@@ -214,9 +218,9 @@ callback_init(void * kernel_end)
                                /* Newer consoles (especially on larger
                                   systems) may require more pages of
                                   PTEs. Grab additional pages as needed. */
-                               if (pmd != pmd_offset(pgd, vaddr)) {
+                               if (pmd != pmd_offset(pud, vaddr)) {
                                        memset(kernel_end, 0, PAGE_SIZE);
-                                       pmd = pmd_offset(pgd, vaddr);
+                                       pmd = pmd_offset(pud, vaddr);
                                        pmd_set(pmd, (pte_t *)kernel_end);
                                        kernel_end += PAGE_SIZE;
                                }
index 4d7b671..26108ea 100644 (file)
@@ -29,6 +29,7 @@ config ARC
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DEBUG_STACKOVERFLOW
+       select HAVE_DEBUG_KMEMLEAK
        select HAVE_FUTEX_CMPXCHG if FUTEX
        select HAVE_IOREMAP_PROT
        select HAVE_KERNEL_GZIP
@@ -45,6 +46,7 @@ config ARC
        select OF_EARLY_FLATTREE
        select PCI_SYSCALL if PCI
        select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
+       select HAVE_ARCH_JUMP_LABEL if ISA_ARCV2 && !CPU_ENDIAN_BE32
 
 config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
@@ -524,6 +526,13 @@ config ARC_DW2_UNWIND
 config ARC_DBG_TLB_PARANOIA
        bool "Paranoia Checks in Low Level TLB Handlers"
 
+config ARC_DBG_JUMP_LABEL
+       bool "Paranoid checks in Static Keys (jump labels) code"
+       depends on JUMP_LABEL
+       default y if STATIC_KEYS_SELFTEST
+       help
+         Enable paranoid checks and self-test of both ARC-specific and generic
+         part of static keys (jump labels) related code.
 endif
 
 config ARC_BUILTIN_DTB_NAME
index f1c44cc..20e9ab6 100644 (file)
@@ -3,7 +3,7 @@
 # Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
 #
 
-KBUILD_DEFCONFIG := nsim_hs_defconfig
+KBUILD_DEFCONFIG := haps_hs_smp_defconfig
 
 ifeq ($(CROSS_COMPILE),)
 CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux-)
index 6ec1fcd..79ec27c 100644 (file)
                        clock-frequency = <750000000>;
                };
 
+               input_clk: input-clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <33333333>;
+               };
+
                core_intc: arc700-intc@cpu {
                        compatible = "snps,arc700-intc";
                        interrupt-controller;
index 305a7f9..c4cfc5f 100644 (file)
@@ -14,6 +14,6 @@
        compatible = "snps,axs101", "snps,arc-sdp";
 
        chosen {
-               bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0 video=1280x720@60 print-fatal-signals=1";
+               bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0 print-fatal-signals=1";
        };
 };
index 46c9136..a934b92 100644 (file)
@@ -17,6 +17,6 @@
        compatible = "snps,axs103", "snps,arc-sdp";
 
        chosen {
-               bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 print-fatal-signals=1 consoleblank=0 video=1280x720@60";
+               bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 print-fatal-signals=1 consoleblank=0";
        };
 };
index 08bcfed..f9a5c9d 100644 (file)
                                clock-frequency = <25000000>;
                                #clock-cells = <0>;
                        };
+               };
 
-                       pguclk: pguclk {
-                               #clock-cells = <0>;
-                               compatible = "fixed-clock";
-                               clock-frequency = <74250000>;
-                       };
+               pguclk: pguclk@10080 {
+                       compatible = "snps,axs10x-pgu-pll-clock";
+                       reg = <0x10080 0x10>, <0x110 0x10>;
+                       #clock-cells = <0>;
+                       clocks = <&input_clk>;
                };
 
                gmac: ethernet@18000 {
index 44bc522..60d578e 100644 (file)
@@ -9,13 +9,15 @@
 / {
        model = "snps,zebu_hs";
        compatible = "snps,zebu_hs";
-       #address-cells = <1>;
-       #size-cells = <1>;
+       #address-cells = <2>;
+       #size-cells = <2>;
        interrupt-parent = <&core_intc>;
 
        memory {
                device_type = "memory";
-               reg = <0x80000000 0x20000000>;  /* 512 */
+               /* CONFIG_LINUX_RAM_BASE needs to match low mem start */
+               reg = <0x0 0x80000000 0x0 0x20000000    /* 512 MB low mem */
+                      0x1 0x00000000 0x0 0x40000000>;  /* 1 GB highmem */
        };
 
        chosen {
@@ -31,8 +33,9 @@
                #address-cells = <1>;
                #size-cells = <1>;
 
-               /* child and parent address space 1:1 mapped */
-               ranges;
+               /* only perip space at end of low mem accessible
+                         bus addr,  parent bus addr, size    */
+               ranges = <0x80000000 0x0 0x80000000 0x80000000>;
 
                core_clk: core_clk {
                        #clock-cells = <0>;
@@ -47,7 +50,7 @@
                };
 
                uart0: serial@f0000000 {
-                       compatible = "ns8250";
+                       compatible = "ns16550a";
                        reg = <0xf0000000 0x2000>;
                        interrupts = <24>;
                        clock-frequency = <50000000>;
index 4d6971c..738c76c 100644 (file)
@@ -54,7 +54,6 @@
                };
 
                uart0: serial@f0000000 {
-                       /* compatible = "ns8250"; Doesn't use FIFOs */
                        compatible = "ns16550a";
                        reg = <0xf0000000 0x2000>;
                        interrupt-parent = <&idu_intc>;
index 63dbaab..f8832a1 100644 (file)
        interrupt-parent = <&core_intc>;
 
        chosen {
-               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8 print-fatal-signals=1";
+               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=ttyS0,115200n8 print-fatal-signals=1";
        };
 
        aliases {
-               serial0 = &arcuart0;
+               serial0 = &uart0;
        };
 
        fpga {
                        #interrupt-cells = <1>;
                };
 
-               arcuart0: serial@c0fc1000 {
-                       compatible = "snps,arc-uart";
-                       reg = <0xc0fc1000 0x100>;
-                       interrupts = <5>;
-                       clock-frequency = <80000000>;
-                       current-speed = <115200>;
-                       status = "okay";
-               };
-
-               ethernet@c0fc2000 {
-                       compatible = "snps,arc-emac";
-                       reg = <0xc0fc2000 0x3c>;
-                       interrupts = <6>;
-                       mac-address = [ 00 11 22 33 44 55 ];
-                       clock-frequency = <80000000>;
-                       max-speed = <100>;
-                       phy = <&phy0>;
-
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       phy0: ethernet-phy@0 {
-                               reg = <1>;
-                       };
+               uart0: serial@f0000000 {
+                       compatible = "ns16550a";
+                       reg = <0xf0000000 0x2000>;
+                       interrupts = <24>;
+                       clock-frequency = <50000000>;
+                       baud = <115200>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       no-loopback-test = <1>;
                };
 
                arcpct0: pct {
diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts
deleted file mode 100644 (file)
index 851798a..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
- */
-/dts-v1/;
-
-/include/ "skeleton_hs.dtsi"
-
-/ {
-       model = "snps,nsim_hs";
-       compatible = "snps,nsim_hs";
-       #address-cells = <2>;
-       #size-cells = <2>;
-       interrupt-parent = <&core_intc>;
-
-       memory {
-               device_type = "memory";
-               /* CONFIG_LINUX_RAM_BASE needs to match low mem start */
-               reg = <0x0 0x80000000 0x0 0x20000000    /* 512 MB low mem */
-                      0x1 0x00000000 0x0 0x40000000>;  /* 1 GB highmem */
-       };
-
-       chosen {
-               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8 print-fatal-signals=1";
-       };
-
-       aliases {
-               serial0 = &arcuart0;
-       };
-
-       fpga {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-
-               /* only perip space at end of low mem accessible
-                        bus addr,   parent bus addr, size */
-               ranges = <0x80000000 0x0 0x80000000 0x80000000>;
-
-               core_clk: core_clk {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <80000000>;
-               };
-
-               core_intc: core-interrupt-controller {
-                       compatible = "snps,archs-intc";
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
-               };
-
-               arcuart0: serial@c0fc1000 {
-                       compatible = "snps,arc-uart";
-                       reg = <0xc0fc1000 0x100>;
-                       interrupts = <24>;
-                       clock-frequency = <80000000>;
-                       current-speed = <115200>;
-                       status = "okay";
-               };
-
-               arcpct0: pct {
-                       compatible = "snps,archs-pct";
-                       #interrupt-cells = <1>;
-                       interrupts = <20>;
-               };
-       };
-};
diff --git a/arch/arc/boot/dts/nsim_hs_idu.dts b/arch/arc/boot/dts/nsim_hs_idu.dts
deleted file mode 100644 (file)
index 6c559a0..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
- */
-/dts-v1/;
-
-/include/ "skeleton_hs_idu.dtsi"
-
-/ {
-       model = "snps,nsim_hs-smp";
-       compatible = "snps,nsim_hs";
-       interrupt-parent = <&core_intc>;
-
-       chosen {
-               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8 print-fatal-signals=1";
-       };
-
-       aliases {
-               serial0 = &arcuart0;
-       };
-
-       fpga {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-
-               /* child and parent address space 1:1 mapped */
-               ranges;
-
-               core_clk: core_clk {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <80000000>;
-               };
-
-               core_intc: core-interrupt-controller {
-                       compatible = "snps,archs-intc";
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
-               };
-
-               idu_intc: idu-interrupt-controller {
-                       compatible = "snps,archs-idu-intc";
-                       interrupt-controller;
-                       interrupt-parent = <&core_intc>;
-                       #interrupt-cells = <1>;
-               };
-
-               arcuart0: serial@c0fc1000 {
-                       compatible = "snps,arc-uart";
-                       reg = <0xc0fc1000 0x100>;
-                       interrupt-parent = <&idu_intc>;
-                       interrupts = <0>;
-                       clock-frequency = <80000000>;
-                       current-speed = <115200>;
-                       status = "okay";
-               };
-
-               arcpct0: pct {
-                       compatible = "snps,archs-pct";
-                       #interrupt-cells = <1>;
-                       interrupts = <20>;
-               };
-       };
-};
index 47ff8a9..7337cdf 100644 (file)
@@ -4,6 +4,7 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_NAMESPACES=y
@@ -15,13 +16,9 @@ CONFIG_EXPERT=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
+CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs"
 CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ISA_ARCV2=y
-CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs"
-CONFIG_PREEMPT=y
 # CONFIG_COMPACTION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -30,9 +27,6 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
@@ -42,21 +36,12 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_VIRTIO_BLK=y
 CONFIG_NETDEVICES=y
 CONFIG_VIRTIO_NET=y
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_BROADCOM is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_VIA is not set
-# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_ETHERNET is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT_EVDEV=y
-CONFIG_MOUSE_PS2_TOUCHKIT=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIO_ARC_PS2=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
@@ -66,9 +51,6 @@ CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_VIRTIO_MMIO=y
index 9685fd5..bc92722 100644 (file)
@@ -4,6 +4,7 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_NAMESPACES=y
@@ -16,15 +17,11 @@ CONFIG_PERF_EVENTS=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
+CONFIG_SMP=y
+CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs_idu"
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ISA_ARCV2=y
-CONFIG_SMP=y
-CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs_idu"
-CONFIG_PREEMPT=y
 # CONFIG_COMPACTION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -33,9 +30,6 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
@@ -43,21 +37,12 @@ CONFIG_DEVTMPFS=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_BLK_DEV is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_BROADCOM is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_VIA is not set
-# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_ETHERNET is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT_EVDEV=y
-CONFIG_MOUSE_PS2_TOUCHKIT=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIO_ARC_PS2=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
@@ -67,9 +52,6 @@ CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_IOMMU_SUPPORT is not set
index 2b9b114..326f6cd 100644 (file)
@@ -4,6 +4,7 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_NAMESPACES=y
@@ -17,13 +18,10 @@ CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_ISA_ARCOMPACT=y
+CONFIG_ARC_BUILTIN_DTB_NAME="nsim_700"
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_BUILTIN_DTB_NAME="nsim_700"
-CONFIG_PREEMPT=y
 # CONFIG_COMPACTION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -37,15 +35,18 @@ CONFIG_DEVTMPFS=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_BLK_DEV is not set
 CONFIG_NETDEVICES=y
-CONFIG_ARC_EMAC=y
-CONFIG_LXT_PHY=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_ETHERNET is not set
+# CONFIG_WLAN is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_ARC=y
-CONFIG_SERIAL_ARC_CONSOLE=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
 # CONFIG_HID is not set
diff --git a/arch/arc/configs/nsim_hs_defconfig b/arch/arc/configs/nsim_hs_defconfig
deleted file mode 100644 (file)
index bab3dd2..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_CROSS_MEMORY_ATTACH is not set
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_EMBEDDED=y
-CONFIG_PERF_EVENTS=y
-# CONFIG_SLUB_DEBUG is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ISA_ARCV2=y
-CONFIG_ARC_BUILTIN_DTB_NAME="nsim_hs"
-CONFIG_PREEMPT=y
-# CONFIG_COMPACTION is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_UNIX_DIAG=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IPV6 is not set
-CONFIG_DEVTMPFS=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_BLK_DEV is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_ARC=y
-CONFIG_SERIAL_ARC_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_HID is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_TMPFS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_NFS_FS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_DEBUG_PREEMPT is not set
diff --git a/arch/arc/configs/nsim_hs_smp_defconfig b/arch/arc/configs/nsim_hs_smp_defconfig
deleted file mode 100644 (file)
index 90d2d50..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-# CONFIG_CROSS_MEMORY_ATTACH is not set
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_EMBEDDED=y
-CONFIG_PERF_EVENTS=y
-# CONFIG_SLUB_DEBUG is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ISA_ARCV2=y
-CONFIG_SMP=y
-CONFIG_ARC_BUILTIN_DTB_NAME="nsim_hs_idu"
-CONFIG_PREEMPT=y
-# CONFIG_COMPACTION is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_UNIX_DIAG=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IPV6 is not set
-CONFIG_DEVTMPFS=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_BLK_DEV is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_ARC=y
-CONFIG_SERIAL_ARC_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_HID is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_TMPFS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_NFS_FS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
index 918804c..d8ece42 100644 (file)
@@ -25,6 +25,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/build_bug.h>
+
 /* Uncached access macros */
 #define arc_read_uncached_32(ptr)      \
 ({                                     \
index 66a2923..c3aa775 100644 (file)
  * to be saved again on kernel mode stack, as part of pt_regs.
  *-------------------------------------------------------------*/
 .macro PROLOG_FREEUP_REG       reg, mem
-#ifdef CONFIG_SMP
+#ifndef ARC_USE_SCRATCH_REG
        sr  \reg, [ARC_REG_SCRATCH_DATA0]
 #else
        st  \reg, [\mem]
 .endm
 
 .macro PROLOG_RESTORE_REG      reg, mem
-#ifdef CONFIG_SMP
+#ifndef ARC_USE_SCRATCH_REG
        lr  \reg, [ARC_REG_SCRATCH_DATA0]
 #else
        ld  \reg, [\mem]
diff --git a/arch/arc/include/asm/jump_label.h b/arch/arc/include/asm/jump_label.h
new file mode 100644 (file)
index 0000000..9d96180
--- /dev/null
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARC_JUMP_LABEL_H
+#define _ASM_ARC_JUMP_LABEL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+/*
+ * NOTE about '.balign 4':
+ *
+ * To make atomic update of patched instruction available we need to guarantee
+ * that this instruction doesn't cross L1 cache line boundary.
+ *
+ * As of today we simply align instruction which can be patched by 4 byte using
+ * ".balign 4" directive. In that case patched instruction is aligned with one
+ * 16-bit NOP_S if this is required.
+ * However 'align by 4' directive is much stricter than it actually required.
+ * It's enough that our 32-bit instruction don't cross L1 cache line boundary /
+ * L1 I$ fetch block boundary which can be achieved by using
+ * ".bundle_align_mode" assembler directive. That will save us from adding
+ * useless NOP_S padding in most of the cases.
+ *
+ * TODO: switch to ".bundle_align_mode" directive using whin it will be
+ * supported by ARC toolchain.
+ */
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+                                              bool branch)
+{
+       asm_volatile_goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)"   \n"
+                "1:                                                    \n"
+                "nop                                                   \n"
+                ".pushsection __jump_table, \"aw\"                     \n"
+                ".word 1b, %l[l_yes], %c0                              \n"
+                ".popsection                                           \n"
+                : : "i" (&((char *)key)[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(".balign "__stringify(JUMP_LABEL_NOP_SIZE)"   \n"
+                "1:                                                    \n"
+                "b %l[l_yes]                                           \n"
+                ".pushsection __jump_table, \"aw\"                     \n"
+                ".word 1b, %l[l_yes], %c0                              \n"
+                ".popsection                                           \n"
+                : : "i" (&((char *)key)[branch]) : : l_yes);
+
+       return false;
+l_yes:
+       return true;
+}
+
+typedef u32 jump_label_t;
+
+struct jump_entry {
+       jump_label_t code;
+       jump_label_t target;
+       jump_label_t key;
+};
+
+#endif  /* __ASSEMBLY__ */
+#endif
index 98cadf1..26b731d 100644 (file)
 #define ARC_REG_SCRATCH_DATA0  0x46c
 #endif
 
+#if defined(CONFIG_ISA_ARCV2) || !defined(CONFIG_SMP)
+#define        ARC_USE_SCRATCH_REG
+#endif
+
 /* Bits in MMU PID register */
 #define __TLB_ENABLE           (1 << 31)
 #define __PROG_ENABLE          (1 << 30)
@@ -63,6 +67,8 @@
 #if (CONFIG_ARC_MMU_VER >= 2)
 #define TLBWriteNI  0x5                /* write JTLB without inv uTLBs */
 #define TLBIVUTLB   0x6                /* explicitly inv uTLBs */
+#else
+#define TLBWriteNI  TLBWrite   /* Not present in hardware, fallback */
 #endif
 
 #if (CONFIG_ARC_MMU_VER >= 4)
index 0354708..3a5e6a5 100644 (file)
@@ -144,7 +144,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         */
        cpumask_set_cpu(cpu, mm_cpumask(next));
 
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
        /* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
 #endif
index b917b59..9019ed9 100644 (file)
@@ -350,7 +350,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
  * Thus use this macro only when you are certain that "current" is current
  * e.g. when dealing with signal frame setup code etc
  */
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
 #define pgd_offset_fast(mm, addr)      \
 ({                                     \
        pgd_t *pgd_base = (pgd_t *) read_aux_reg(ARC_REG_SCRATCH_DATA0);  \
index de62511..e784f53 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARC_EMUL_UNALIGNED)      += unaligned.o
 obj-$(CONFIG_KGDB)                     += kgdb.o
 obj-$(CONFIG_ARC_METAWARE_HLINK)       += arc_hostlink.o
 obj-$(CONFIG_PERF_EVENTS)              += perf_event.o
+obj-$(CONFIG_JUMP_LABEL)               += jump_label.o
 
 obj-$(CONFIG_ARC_FPU_SAVE_RESTORE)     += fpu.o
 CFLAGS_fpu.o   += -mdpfp
diff --git a/arch/arc/kernel/jump_label.c b/arch/arc/kernel/jump_label.c
new file mode 100644 (file)
index 0000000..b8600dc
--- /dev/null
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kernel.h>
+#include <linux/jump_label.h>
+
+#include "asm/cacheflush.h"
+
+#define JUMPLABEL_ERR  "ARC: jump_label: ERROR: "
+
+/* Halt system on fatal error to make debug easier */
+#define arc_jl_fatal(format...)                                                \
+({                                                                     \
+       pr_err(JUMPLABEL_ERR format);                                   \
+       BUG();                                                          \
+})
+
+static inline u32 arc_gen_nop(void)
+{
+       /* 1x 32bit NOP in middle endian */
+       return 0x7000264a;
+}
+
+/*
+ * Atomic update of patched instruction is only available if this
+ * instruction doesn't cross L1 cache line boundary. You can read about
+ * the way we achieve this in arc/include/asm/jump_label.h
+ */
+static inline void instruction_align_assert(void *addr, int len)
+{
+       unsigned long a = (unsigned long)addr;
+
+       if ((a >> L1_CACHE_SHIFT) != ((a + len - 1) >> L1_CACHE_SHIFT))
+               arc_jl_fatal("instruction (addr %px) cross L1 cache line border",
+                            addr);
+}
+
+/*
+ * ARCv2 'Branch unconditionally' instruction:
+ * 00000ssssssssss1SSSSSSSSSSNRtttt
+ * s S[n:0] lower bits signed immediate (number is bitfield size)
+ * S S[m:n+1] upper bits signed immediate (number is bitfield size)
+ * t S[24:21] upper bits signed immediate (branch unconditionally far)
+ * N N <.d> delay slot mode
+ * R R Reserved
+ */
+static inline u32 arc_gen_branch(jump_label_t pc, jump_label_t target)
+{
+       u32 instruction_l, instruction_r;
+       u32 pcl = pc & GENMASK(31, 2);
+       u32 u_offset = target - pcl;
+       u32 s, S, t;
+
+       /*
+        * Offset in 32-bit branch instruction must to fit into s25.
+        * Something is terribly broken if we get such huge offset within one
+        * function.
+        */
+       if ((s32)u_offset < -16777216 || (s32)u_offset > 16777214)
+               arc_jl_fatal("gen branch with offset (%d) not fit in s25",
+                            (s32)u_offset);
+
+       /*
+        * All instructions are aligned by 2 bytes so we should never get offset
+        * here which is not 2 bytes aligned.
+        */
+       if (u_offset & 0x1)
+               arc_jl_fatal("gen branch with offset (%d) unaligned to 2 bytes",
+                            (s32)u_offset);
+
+       s = (u_offset >> 1)  & GENMASK(9, 0);
+       S = (u_offset >> 11) & GENMASK(9, 0);
+       t = (u_offset >> 21) & GENMASK(3, 0);
+
+       /* 00000ssssssssss1 */
+       instruction_l = (s << 1) | 0x1;
+       /* SSSSSSSSSSNRtttt */
+       instruction_r = (S << 6) | t;
+
+       return (instruction_r << 16) | (instruction_l & GENMASK(15, 0));
+}
+
+void arch_jump_label_transform(struct jump_entry *entry,
+                              enum jump_label_type type)
+{
+       jump_label_t *instr_addr = (jump_label_t *)entry->code;
+       u32 instr;
+
+       instruction_align_assert(instr_addr, JUMP_LABEL_NOP_SIZE);
+
+       if (type == JUMP_LABEL_JMP)
+               instr = arc_gen_branch(entry->code, entry->target);
+       else
+               instr = arc_gen_nop();
+
+       WRITE_ONCE(*instr_addr, instr);
+       flush_icache_range(entry->code, entry->code + JUMP_LABEL_NOP_SIZE);
+}
+
+void arch_jump_label_transform_static(struct jump_entry *entry,
+                                     enum jump_label_type type)
+{
+       /*
+        * We use only one NOP type (1x, 4 byte) in arch_static_branch, so
+        * there's no need to patch an identical NOP over the top of it here.
+        * The generic code calls 'arch_jump_label_transform' if the NOP needs
+        * to be replaced by a branch, so 'arch_jump_label_transform_static' is
+        * never called with type other than JUMP_LABEL_NOP.
+        */
+       BUG_ON(type != JUMP_LABEL_NOP);
+}
+
+#ifdef CONFIG_ARC_DBG_JUMP_LABEL
+#define SELFTEST_MSG   "ARC: instruction generation self-test: "
+
+struct arc_gen_branch_testdata {
+       jump_label_t pc;
+       jump_label_t target_address;
+       u32 expected_instr;
+};
+
+static __init int branch_gen_test(const struct arc_gen_branch_testdata *test)
+{
+       u32 instr_got;
+
+       instr_got = arc_gen_branch(test->pc, test->target_address);
+       if (instr_got == test->expected_instr)
+               return 0;
+
+       pr_err(SELFTEST_MSG "FAIL:\n arc_gen_branch(0x%08x, 0x%08x) != 0x%08x, got 0x%08x\n",
+              test->pc, test->target_address,
+              test->expected_instr, instr_got);
+
+       return -EFAULT;
+}
+
+/*
+ * Offset field in branch instruction is not continuous. Test all
+ * available offset field and sign combinations. Test data is generated
+ * from real working code.
+ */
+static const struct arc_gen_branch_testdata arcgenbr_test_data[] __initconst = {
+       {0x90007548, 0x90007514, 0xffcf07cd}, /* tiny (-52) offs */
+       {0x9000c9c0, 0x9000c782, 0xffcf05c3}, /* tiny (-574) offs */
+       {0x9000cc1c, 0x9000c782, 0xffcf0367}, /* tiny (-1178) offs */
+       {0x9009dce0, 0x9009d106, 0xff8f0427}, /* small (-3034) offs */
+       {0x9000f5de, 0x90007d30, 0xfc0f0755}, /* big  (-30892) offs */
+       {0x900a2444, 0x90035f64, 0xc9cf0321}, /* huge (-443616) offs */
+       {0x90007514, 0x9000752c, 0x00000019}, /* tiny (+24) offs */
+       {0x9001a578, 0x9001a77a, 0x00000203}, /* tiny (+514) offs */
+       {0x90031ed8, 0x90032634, 0x0000075d}, /* tiny (+1884) offs */
+       {0x9008c7f2, 0x9008d3f0, 0x00400401}, /* small (+3072) offs */
+       {0x9000bb38, 0x9003b340, 0x17c00009}, /* big  (+194568) offs */
+       {0x90008f44, 0x90578d80, 0xb7c2063d}  /* huge (+5701180) offs */
+};
+
+static __init int instr_gen_test(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(arcgenbr_test_data); i++)
+               if (branch_gen_test(&arcgenbr_test_data[i]))
+                       return -EFAULT;
+
+       pr_info(SELFTEST_MSG "OK\n");
+
+       return 0;
+}
+early_initcall(instr_gen_test);
+
+#endif /* CONFIG_ARC_DBG_JUMP_LABEL */
index dc05a63..27ea64b 100644 (file)
@@ -42,10 +42,10 @@ do {                                                \
 
 #define EXTRA_INFO(f) { \
                BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
-                               % FIELD_SIZEOF(struct unwind_frame_info, f)) \
+                               % sizeof_field(struct unwind_frame_info, f)) \
                                + offsetof(struct unwind_frame_info, f) \
-                               / FIELD_SIZEOF(struct unwind_frame_info, f), \
-                               FIELD_SIZEOF(struct unwind_frame_info, f) \
+                               / sizeof_field(struct unwind_frame_info, f), \
+                               sizeof_field(struct unwind_frame_info, f) \
        }
 #define PTREGS_INFO(f) EXTRA_INFO(regs.f)
 
index 10025e1..c340acd 100644 (file)
@@ -118,6 +118,33 @@ static inline void __tlb_entry_erase(void)
        write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite);
 }
 
+static void utlb_invalidate(void)
+{
+#if (CONFIG_ARC_MMU_VER >= 2)
+
+#if (CONFIG_ARC_MMU_VER == 2)
+       /* MMU v2 introduced the uTLB Flush command.
+        * There was however an obscure hardware bug, where uTLB flush would
+        * fail when a prior probe for J-TLB (both totally unrelated) would
+        * return lkup err - because the entry didn't exist in MMU.
+        * The Workround was to set Index reg with some valid value, prior to
+        * flush. This was fixed in MMU v3
+        */
+       unsigned int idx;
+
+       /* make sure INDEX Reg is valid */
+       idx = read_aux_reg(ARC_REG_TLBINDEX);
+
+       /* If not write some dummy val */
+       if (unlikely(idx & TLB_LKUP_ERR))
+               write_aux_reg(ARC_REG_TLBINDEX, 0xa);
+#endif
+
+       write_aux_reg(ARC_REG_TLBCOMMAND, TLBIVUTLB);
+#endif
+
+}
+
 #if (CONFIG_ARC_MMU_VER < 4)
 
 static inline unsigned int tlb_entry_lkup(unsigned long vaddr_n_asid)
@@ -149,44 +176,6 @@ static void tlb_entry_erase(unsigned int vaddr_n_asid)
        }
 }
 
-/****************************************************************************
- * ARC700 MMU caches recently used J-TLB entries (RAM) as uTLBs (FLOPs)
- *
- * New IVUTLB cmd in MMU v2 explictly invalidates the uTLB
- *
- * utlb_invalidate ( )
- *  -For v2 MMU calls Flush uTLB Cmd
- *  -For v1 MMU does nothing (except for Metal Fix v1 MMU)
- *      This is because in v1 TLBWrite itself invalidate uTLBs
- ***************************************************************************/
-
-static void utlb_invalidate(void)
-{
-#if (CONFIG_ARC_MMU_VER >= 2)
-
-#if (CONFIG_ARC_MMU_VER == 2)
-       /* MMU v2 introduced the uTLB Flush command.
-        * There was however an obscure hardware bug, where uTLB flush would
-        * fail when a prior probe for J-TLB (both totally unrelated) would
-        * return lkup err - because the entry didn't exist in MMU.
-        * The Workround was to set Index reg with some valid value, prior to
-        * flush. This was fixed in MMU v3 hence not needed any more
-        */
-       unsigned int idx;
-
-       /* make sure INDEX Reg is valid */
-       idx = read_aux_reg(ARC_REG_TLBINDEX);
-
-       /* If not write some dummy val */
-       if (unlikely(idx & TLB_LKUP_ERR))
-               write_aux_reg(ARC_REG_TLBINDEX, 0xa);
-#endif
-
-       write_aux_reg(ARC_REG_TLBCOMMAND, TLBIVUTLB);
-#endif
-
-}
-
 static void tlb_entry_insert(unsigned int pd0, pte_t pd1)
 {
        unsigned int idx;
@@ -219,11 +208,6 @@ static void tlb_entry_insert(unsigned int pd0, pte_t pd1)
 
 #else  /* CONFIG_ARC_MMU_VER >= 4) */
 
-static void utlb_invalidate(void)
-{
-       /* No need since uTLB is always in sync with JTLB */
-}
-
 static void tlb_entry_erase(unsigned int vaddr_n_asid)
 {
        write_aux_reg(ARC_REG_TLBPD0, vaddr_n_asid | _PAGE_PRESENT);
@@ -267,7 +251,7 @@ noinline void local_flush_tlb_all(void)
        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);
+               write_aux_reg(ARC_REG_TLBCOMMAND, TLBWriteNI);
        }
 
        if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
@@ -278,7 +262,7 @@ noinline void local_flush_tlb_all(void)
 
                for (entry = stlb_idx; entry < stlb_idx + 16; entry++) {
                        write_aux_reg(ARC_REG_TLBINDEX, entry);
-                       write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite);
+                       write_aux_reg(ARC_REG_TLBCOMMAND, TLBWriteNI);
                }
        }
 
@@ -355,8 +339,6 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                }
        }
 
-       utlb_invalidate();
-
        local_irq_restore(flags);
 }
 
@@ -385,8 +367,6 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
                start += PAGE_SIZE;
        }
 
-       utlb_invalidate();
-
        local_irq_restore(flags);
 }
 
@@ -407,7 +387,6 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 
        if (asid_mm(vma->vm_mm, cpu) != MM_CTXT_NO_ASID) {
                tlb_entry_erase((page & PAGE_MASK) | hw_pid(vma->vm_mm, cpu));
-               utlb_invalidate();
        }
 
        local_irq_restore(flags);
@@ -868,7 +847,7 @@ void arc_mmu_init(void)
        write_aux_reg(ARC_REG_PID, MMU_ENABLE);
 
        /* In smp we use this reg for interrupt 1 scratch */
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
        /* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
 #endif
index c55d95d..2efaf6c 100644 (file)
@@ -122,17 +122,27 @@ ex_saved_reg1:
 #else  /* ARCv2 */
 
 .macro TLBMISS_FREEUP_REGS
+#ifdef CONFIG_ARC_HAS_LL64
+       std   r0, [sp, -16]
+       std   r2, [sp, -8]
+#else
        PUSH  r0
        PUSH  r1
        PUSH  r2
        PUSH  r3
+#endif
 .endm
 
 .macro TLBMISS_RESTORE_REGS
+#ifdef CONFIG_ARC_HAS_LL64
+       ldd   r0, [sp, -16]
+       ldd   r2, [sp, -8]
+#else
        POP   r3
        POP   r2
        POP   r1
        POP   r0
+#endif
 .endm
 
 #endif
@@ -193,7 +203,7 @@ ex_saved_reg1:
 
        lr  r2, [efa]
 
-#ifndef CONFIG_SMP
+#ifdef ARC_USE_SCRATCH_REG
        lr  r1, [ARC_REG_SCRATCH_DATA0] ; current pgd
 #else
        GET_CURR_TASK_ON_CPU  r1
@@ -282,11 +292,7 @@ ex_saved_reg1:
        sr  TLBGetIndex, [ARC_REG_TLBCOMMAND]
 
        /* Commit the Write */
-#if (CONFIG_ARC_MMU_VER >= 2)   /* introduced in v2 */
        sr TLBWriteNI, [ARC_REG_TLBCOMMAND]
-#else
-       sr TLBWrite, [ARC_REG_TLBCOMMAND]
-#endif
 
 #else
        sr TLBInsertEntry, [ARC_REG_TLBCOMMAND]
@@ -370,9 +376,7 @@ ENTRY(EV_TLBMissD)
 
        ;----------------------------------------------------------------
        ; UPDATE_PTE: Let Linux VM know that page was accessed/dirty
-       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_DIRTY           ; if Write, set Dirty bit as well
        st_s    r0, [r1]                      ; Write back PTE
 
index 3765ded..2bde2a6 100644 (file)
@@ -21,7 +21,6 @@ static const char *simulation_compat[] __initconst = {
        "snps,nsim",
        "snps,nsimosci",
 #else
-       "snps,nsim_hs",
        "snps,nsimosci_hs",
        "snps,zebu_hs",
 #endif
index 5aed42e..ba75e36 100644 (file)
@@ -1357,7 +1357,7 @@ config ARCH_NR_GPIO
        int
        default 2048 if ARCH_SOCFPGA
        default 1024 if ARCH_BRCMSTB || ARCH_RENESAS || ARCH_TEGRA || \
-               ARCH_ZYNQ
+               ARCH_ZYNQ || ARCH_ASPEED
        default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
                SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
        default 416 if ARCH_SUNXI
index b21b3a6..08011dc 100644 (file)
@@ -45,7 +45,8 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
        at91sam9x25ek.dtb \
        at91sam9x35ek.dtb
 dtb-$(CONFIG_SOC_SAM_V7) += \
-       at91-kizbox2.dtb \
+       at91-kizbox2-2.dtb \
+       at91-kizbox3-hs.dtb \
        at91-nattis-2-natte-2.dtb \
        at91-sama5d27_som1_ek.dtb \
        at91-sama5d2_ptc_ek.dtb \
@@ -83,6 +84,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
        bcm2837-rpi-3-b.dtb \
        bcm2837-rpi-3-b-plus.dtb \
        bcm2837-rpi-cm3-io3.dtb \
+       bcm2711-rpi-4-b.dtb \
        bcm2835-rpi-zero.dtb \
        bcm2835-rpi-zero-w.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += \
@@ -113,6 +115,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
        bcm47094-luxul-abr-4500.dtb \
        bcm47094-luxul-xap-1610.dtb \
        bcm47094-luxul-xbr-4500.dtb \
+       bcm47094-luxul-xwc-2000.dtb \
        bcm47094-luxul-xwr-3100.dtb \
        bcm47094-luxul-xwr-3150-v1.dtb \
        bcm47094-netgear-r8500.dtb \
@@ -337,7 +340,8 @@ dtb-$(CONFIG_ARCH_MMP) += \
        pxa168-aspenite.dtb \
        pxa910-dkb.dtb \
        mmp2-brownstone.dtb \
-       mmp2-olpc-xo-1-75.dtb
+       mmp2-olpc-xo-1-75.dtb \
+       mmp3-dell-ariel.dtb
 dtb-$(CONFIG_ARCH_MPS2) += \
        mps2-an385.dtb \
        mps2-an399.dtb
@@ -552,7 +556,8 @@ dtb-$(CONFIG_SOC_IMX6SL) += \
        imx6sl-evk.dtb \
        imx6sl-warp.dtb
 dtb-$(CONFIG_SOC_IMX6SLL) += \
-       imx6sll-evk.dtb
+       imx6sll-evk.dtb \
+       imx6sll-kobo-clarahd.dtb
 dtb-$(CONFIG_SOC_IMX6SX) += \
        imx6sx-nitrogen6sx.dtb \
        imx6sx-sabreauto.dtb \
@@ -583,6 +588,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
        imx6ull-14x14-evk.dtb \
        imx6ull-colibri-eval-v3.dtb \
        imx6ull-colibri-wifi-eval-v3.dtb \
+       imx6ull-opos6uldev.dtb \
        imx6ull-phytec-segin-ff-rdk-nand.dtb \
        imx6ull-phytec-segin-ff-rdk-emmc.dtb \
        imx6ull-phytec-segin-lc-rdk-nand.dtb \
@@ -753,6 +759,9 @@ dtb-$(CONFIG_SOC_AM33XX) += \
        am335x-moxa-uc-2101.dtb \
        am335x-moxa-uc-8100-me-t.dtb \
        am335x-nano.dtb \
+       am335x-netcan-plus-1xx.dtb \
+       am335x-netcom-plus-2xx.dtb \
+       am335x-netcom-plus-8xx.dtb \
        am335x-pdu001.dtb \
        am335x-pepper.dtb \
        am335x-phycore-rdk.dtb \
@@ -765,6 +774,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
        am335x-wega-rdk.dtb \
        am335x-osd3358-sm-red.dtb
 dtb-$(CONFIG_ARCH_OMAP4) += \
+       omap4-droid-bionic-xt875.dtb \
        omap4-droid4-xt894.dtb \
        omap4-duovero-parlor.dtb \
        omap4-kc1.dtb \
@@ -1105,6 +1115,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
        sun8i-h3-beelink-x2.dtb \
        sun8i-h3-libretech-all-h3-cc.dtb \
        sun8i-h3-mapleboard-mp130.dtb \
+       sun8i-h3-nanopi-duo2.dtb \
        sun8i-h3-nanopi-m1.dtb  \
        sun8i-h3-nanopi-m1-plus.dtb \
        sun8i-h3-nanopi-neo.dtb \
@@ -1288,6 +1299,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
        aspeed-bmc-facebook-wedge40.dtb \
        aspeed-bmc-facebook-wedge100.dtb \
        aspeed-bmc-facebook-yamp.dtb \
+       aspeed-bmc-ibm-rainier.dtb \
        aspeed-bmc-intel-s2600wf.dtb \
        aspeed-bmc-inspur-fp5280g2.dtb \
        aspeed-bmc-lenovo-hr630.dtb \
@@ -1298,6 +1310,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
        aspeed-bmc-opp-palmetto.dtb \
        aspeed-bmc-opp-romulus.dtb \
        aspeed-bmc-opp-swift.dtb \
+       aspeed-bmc-opp-tacoma.dtb \
        aspeed-bmc-opp-vesnin.dtb \
        aspeed-bmc-opp-witherspoon.dtb \
        aspeed-bmc-opp-zaius.dtb \
index ed235f2..05e7b5d 100644 (file)
        };
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&cppi41dma  {
-       status = "okay";
-};
-
 #include "tps65910.dtsi"
 
 &tps {
index 89b4cf2..6c9187b 100644 (file)
        status = "okay";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "peripheral";
        interrupts-extended = <&intc 18 &tps 0>;
        interrupt-names = "mc", "vbus";
 };
 
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &i2c0 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0_pins>;
index 2f6652e..5811fb8 100644 (file)
        status = "okay";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "peripheral";
        interrupts-extended = <&intc 18 &tps 0>;
        interrupt-names = "mc", "vbus";
 };
 
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &i2c0 {
        baseboard_eeprom: baseboard_eeprom@50 {
                compatible = "atmel,24c256";
index 8cd81dc..b14a275 100644 (file)
 };
 
 /* USB */
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb1 {
        pinctrl-names = "default";
        pinctrl-0 = <&usb1_drvvbus>;
-
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 /* microSD */
 &mmc1 {
        pinctrl-names = "default";
index 1fe3b56..c6fe9db 100644 (file)
@@ -330,26 +330,6 @@ status = "okay";
        };
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
-&cppi41dma  {
-       status = "okay";
-};
-
 &epwmss0 {
        status = "okay";
 
index a001457..6f0a6be 100644 (file)
        };
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins>;
index e28a5b8..a97f9df 100644 (file)
        };
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &epwmss2 {
        status = "okay";
 
index c9611ea..81e0f63 100644 (file)
        };
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &elm {
        status = "okay";
 };
        status = "okay";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
 &usb0 {
        dr_mode = "peripheral";
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
 };
 
 &usb1 {
        dr_mode = "host";
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
 };
 
 &am33xx_pinmux {
index eabcc8b..c9f354f 100644 (file)
        pinctrl-0 = <&uart0_pins>;
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 #include "tps65910.dtsi"
 
 &tps {
index a8005e9..fef5828 100644 (file)
        status = "okay";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "host";
 };
 
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &cpsw_emac0 {
        phy-handle = <&ethphy0>;
        phy-mode = "rmii";
index 671d4a5..6495a12 100644 (file)
        };
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 /* Power */
 &vbat {
        regulator-name = "vbat";
index 783d411..244df9c 100644 (file)
        };
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "host";
 };
 
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 #include "tps65910.dtsi"
 
 &tps {
diff --git a/arch/arm/boot/dts/am335x-netcan-plus-1xx.dts b/arch/arm/boot/dts/am335x-netcan-plus-1xx.dts
new file mode 100644 (file)
index 0000000..1e4dbc8
--- /dev/null
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/*
+ * VScom OnRISC
+ * http://www.vscom.de
+ */
+
+/dts-v1/;
+
+#include "am335x-baltos.dtsi"
+#include "am335x-baltos-leds.dtsi"
+
+/ {
+       model = "NetCAN";
+
+       leds {
+               pinctrl-names = "default";
+               pinctrl-0 = <&user_leds_s0>;
+
+               compatible = "gpio-leds";
+
+               led@1 {
+                       label = "can_data";
+                       linux,default-trigger = "netdev";
+                       gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+               led@2 {
+                       label = "can_error";
+                       gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+       };
+};
+
+&am33xx_pinmux {
+       user_leds_s0: user_leds_s0 {
+               pinctrl-single,pins = <
+                       AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_OUTPUT_PULLDOWN, MUX_MODE7)    /* CAN Data LED */
+                       AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_OUTPUT_PULLDOWN, MUX_MODE7)    /* CAN Error LED */
+               >;
+       };
+
+       dcan1_pins: pinmux_dcan1_pins {
+               pinctrl-single,pins = <
+                       AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_OUTPUT, MUX_MODE2)    /* CAN TX */
+                       AM33XX_PADCONF(AM335X_PIN_UART0_RTSN, PIN_INPUT, MUX_MODE2)     /* CAN RX */
+               >;
+       };
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&davinci_mdio {
+       phy0: ethernet-phy@0 {
+               reg = <1>;
+       };
+};
+
+&cpsw_emac0 {
+       phy-mode = "rmii";
+       dual_emac_res_vlan = <1>;
+       phy-handle = <&phy0>;
+};
+
+&cpsw_emac1 {
+       phy-mode = "rgmii-id";
+       dual_emac_res_vlan = <2>;
+       phy-handle = <&phy1>;
+};
+
+&dcan1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&dcan1_pins>;
+
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/am335x-netcom-plus-2xx.dts
new file mode 100644 (file)
index 0000000..9a6cd8e
--- /dev/null
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/*
+ * VScom OnRISC
+ * http://www.vscom.de
+ */
+
+/dts-v1/;
+
+#include "am335x-baltos.dtsi"
+#include "am335x-baltos-leds.dtsi"
+
+/ {
+       model = "NetCom Plus";
+};
+
+&am33xx_pinmux {
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+                       AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT, MUX_MODE0)                      /* RX */
+                       AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_INPUT, MUX_MODE0)                      /* TX */
+                       AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT_PULLDOWN, MUX_MODE0)            /* CTS */
+                       AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_OUTPUT_PULLDOWN, MUX_MODE0)           /* RTS */
+                       AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE7)            /* DTR */
+                       AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_INPUT_PULLDOWN, MUX_MODE7)             /* DSR */
+                       AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_INPUT_PULLDOWN, MUX_MODE7)              /* DCD */
+                       AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_INPUT_PULLDOWN, MUX_MODE7)        /* RI */
+               >;
+       };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT, MUX_MODE1)              /* RX */
+                       AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_OUTPUT, MUX_MODE1)               /* TX */
+                       AM33XX_PADCONF(AM335X_PIN_I2C0_SDA, PIN_INPUT_PULLDOWN, MUX_MODE2)      /* CTS */
+                       AM33XX_PADCONF(AM335X_PIN_I2C0_SCL, PIN_OUTPUT_PULLDOWN, MUX_MODE2)     /* RTS */
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_OUTPUT_PULLDOWN, MUX_MODE7)    /* DTR */
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT_PULLDOWN, MUX_MODE7)     /* DSR */
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_INPUT_PULLDOWN, MUX_MODE7)     /* DCD */
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLDOWN, MUX_MODE7)     /* RI */
+               >;
+       };
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+       dtr-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+       dsr-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
+       dcd-gpios = <&gpio2 24 GPIO_ACTIVE_LOW>;
+       rng-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>;
+
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+       dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+       dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+       rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+
+       status = "okay";
+};
+
+&davinci_mdio {
+       phy0: ethernet-phy@0 {
+               reg = <1>;
+       };
+};
+
+&cpsw_emac0 {
+       phy-mode = "rmii";
+       dual_emac_res_vlan = <1>;
+       phy-handle = <&phy0>;
+};
+
+&cpsw_emac1 {
+       phy-mode = "rgmii-id";
+       dual_emac_res_vlan = <2>;
+       phy-handle = <&phy1>;
+};
diff --git a/arch/arm/boot/dts/am335x-netcom-plus-8xx.dts b/arch/arm/boot/dts/am335x-netcom-plus-8xx.dts
new file mode 100644 (file)
index 0000000..2298563
--- /dev/null
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/*
+ * VScom OnRISC
+ * http://www.vscom.de
+ */
+
+/dts-v1/;
+
+#include "am335x-baltos.dtsi"
+
+/ {
+       model = "NetCom Plus";
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&dip_switches>;
+
+       dip_switches: pinmux_dip_switches {
+               pinctrl-single,pins = <
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT_PULLDOWN, MUX_MODE7)
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT_PULLDOWN, MUX_MODE7)
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_INPUT_PULLDOWN, MUX_MODE7)
+                       AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLDOWN, MUX_MODE7)
+               >;
+       };
+
+       tca6416_pins: pinmux_tca6416_pins {
+               pinctrl-single,pins = <
+                       AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR1, PIN_INPUT_PULLUP, MUX_MODE7)
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT_PULLDOWN, MUX_MODE3)
+                       AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_INPUT_PULLDOWN, MUX_MODE3)
+               >;
+       };
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb1_phy {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&usb1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&i2c1 {
+       tca6416a: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <20 IRQ_TYPE_EDGE_RISING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tca6416_pins>;
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       tca6416b: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       tca6416c: gpio@21 {
+               compatible = "ti,tca6416";
+               reg = <0x21>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&davinci_mdio {
+       phy0: ethernet-phy@0 {
+               reg = <1>;
+       };
+};
+
+&cpsw_emac0 {
+       phy-mode = "rmii";
+       dual_emac_res_vlan = <1>;
+       phy-handle = <&phy0>;
+};
+
+&cpsw_emac1 {
+       phy-mode = "rgmii-id";
+       dual_emac_res_vlan = <2>;
+       phy-handle = <&phy1>;
+};
index f47cc9f..1d29020 100644 (file)
        status = "okay";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "peripheral";
        interrupts-extended = <&intc 18 &tps 0>;
        interrupt-names = "mc", "vbus";
 };
 
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &i2c2 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins>;
index 9bfa032..6c547c8 100644 (file)
 };
 
 /* USB */
-&cppi41dma {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
-
-&usb1_phy {
-       status = "okay";
-};
index 3141255..e4dcfa0 100644 (file)
        };
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
-&usb1 {
-       status = "okay";
-};
-
-&cppi41dma  {
-       status = "okay";
-};
-
 /*
  * Disable soc's rtc as we have no VBAT for it. This makes the board
  * rtc (Microchip MCP79400) the default rtc device 'rtc0'.
index e7764ec..6d7608d 100644 (file)
 
 /* USB */
 &usb {
-       status = "okay";
-
        pinctrl-names = "default";
        pinctrl-0 = <&usb_pins>;
 };
 
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
         dr_mode = "host";
 };
 
 &usb1 {
-       status = "okay";
         dr_mode = "host";
 };
 
-&cppi41dma {
-       status = "okay";
-};
-
 &am33xx_pinmux {
        usb_pins: pinmux_usb {
                pinctrl-single,pins = <
index ff4f919..4da7190 100644 (file)
        status = "okay";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "otg";
 };
 
-&usb1_phy {
-       status = "okay";
-};
-
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
-
-&cppi41dma  {
-       status = "okay";
-};
index 5aff02a..6fbf4ac 100644 (file)
        status = "okay";
        linux,rs485-enabled-at-boot-time;
 };
-
-/* USB */
-&cppi41dma {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
index 8678e6e..e5fdb7a 100644 (file)
 
 &cpsw_emac0 {
        phy-handle = <&ethphy0>;
-       phy-mode = "rgmii-txid";
+       phy-mode = "rgmii-id";
 };
 
 &i2c0 {
index 5b03685..1eaa265 100644 (file)
        status = "okay";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &davinci_mdio {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = <&davinci_mdio_default>;
        status = "okay";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
index 2f82095..f4684c8 100644 (file)
        status = "disabled";
 };
 
-&usb {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
-};
-
 &usb0 {
-       status = "okay";
        dr_mode = "otg";
 };
 
 &usb1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&cppi41dma  {
-       status = "okay";
-};
-
 &mmc1 {
        status = "okay";
        pinctrl-names = "default";
index 61fc4cd..1359bf8 100644 (file)
        status = "okay";
 };
 
-/* USB */
-&cppi41dma {
-       status = "okay";
-};
-
-&usb_ctrl_mod {
-       status = "okay";
-};
-
-&usb {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-};
-
-&usb0_phy {
-       status = "okay";
-};
-
 &usb1 {
        dr_mode = "host";
-       status = "okay";
-};
-
-&usb1_phy {
-       status = "okay";
 };
index 7a9eb2b..3a8a205 100644 (file)
 
                gpio0_target: target-module@7000 {      /* 0x44e07000, ap 14 20.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio1";
                        reg = <0x7000 0x4>,
                              <0x7010 0x4>,
                              <0x7114 0x4>;
 
                target-module@9000 {                    /* 0x44e09000, ap 16 04.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart1";
                        reg = <0x9050 0x4>,
                              <0x9054 0x4>,
                              <0x9058 0x4>;
 
                target-module@b000 {                    /* 0x44e0b000, ap 18 48.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c1";
                        reg = <0xb000 0x8>,
                              <0xb010 0x8>,
                              <0xb090 0x8>;
                                        };
                                };
 
+                               usb_ctrl_mod: control@620 {
+                                       compatible = "ti,am335x-usb-ctrl-module";
+                                       reg = <0x620 0x10>,
+                                             <0x648 0x4>;
+                                       reg-names = "phy_ctrl", "wakeup";
+                               };
+
                                wkup_m3_ipc: wkup_m3_ipc@1324 {
                                        compatible = "ti,am3352-wkup-m3-ipc";
                                        reg = <0x1324 0x24>;
 
                target-module@35000 {                   /* 0x44e35000, ap 29 50.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "wd_timer2";
                        reg = <0x35000 0x4>,
                              <0x35010 0x4>,
                              <0x35014 0x4>;
 
                target-module@22000 {                   /* 0x48022000, ap 10 12.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart2";
                        reg = <0x22050 0x4>,
                              <0x22054 0x4>,
                              <0x22058 0x4>;
 
                target-module@24000 {                   /* 0x48024000, ap 12 14.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart3";
                        reg = <0x24050 0x4>,
                              <0x24054 0x4>,
                              <0x24058 0x4>;
 
                target-module@2a000 {                   /* 0x4802a000, ap 14 2a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c2";
                        reg = <0x2a000 0x8>,
                              <0x2a010 0x8>,
                              <0x2a090 0x8>;
 
                target-module@38000 {                   /* 0x48038000, ap 16 02.0 */
                        compatible = "ti,sysc-omap4-simple", "ti,sysc";
-                       ti,hwmods = "mcasp0";
                        reg = <0x38000 0x4>,
                              <0x38004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3c000 {                   /* 0x4803c000, ap 20 32.0 */
                        compatible = "ti,sysc-omap4-simple", "ti,sysc";
-                       ti,hwmods = "mcasp1";
                        reg = <0x3c000 0x4>,
                              <0x3c004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@4c000 {                   /* 0x4804c000, ap 32 36.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio2";
                        reg = <0x4c000 0x4>,
                              <0x4c010 0x4>,
                              <0x4c114 0x4>;
 
                target-module@60000 {                   /* 0x48060000, ap 36 0c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmc1";
                        reg = <0x602fc 0x4>,
                              <0x60110 0x4>,
                              <0x60114 0x4>;
 
                target-module@c8000 {                   /* 0x480c8000, ap 87 06.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox";
                        reg = <0xc8000 0x4>,
                              <0xc8010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@9c000 {                   /* 0x4819c000, ap 46 5a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c3";
                        reg = <0x9c000 0x8>,
                              <0x9c010 0x8>,
                              <0x9c090 0x8>;
 
                target-module@a6000 {                   /* 0x481a6000, ap 48 16.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart4";
                        reg = <0xa6050 0x4>,
                              <0xa6054 0x4>,
                              <0xa6058 0x4>;
 
                target-module@a8000 {                   /* 0x481a8000, ap 50 20.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart5";
                        reg = <0xa8050 0x4>,
                              <0xa8054 0x4>,
                              <0xa8058 0x4>;
 
                target-module@aa000 {                   /* 0x481aa000, ap 52 1a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart6";
                        reg = <0xaa050 0x4>,
                              <0xaa054 0x4>,
                              <0xaa058 0x4>;
 
                target-module@ac000 {                   /* 0x481ac000, ap 54 38.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio3";
                        reg = <0xac000 0x4>,
                              <0xac010 0x4>,
                              <0xac114 0x4>;
 
                target-module@ae000 {                   /* 0x481ae000, ap 56 3a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio4";
                        reg = <0xae000 0x4>,
                              <0xae010 0x4>,
                              <0xae114 0x4>;
 
                target-module@d8000 {                   /* 0x481d8000, ap 64 66.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmc2";
                        reg = <0xd82fc 0x4>,
                              <0xd8110 0x4>,
                              <0xd8114 0x4>;
 
                target-module@10000 {                   /* 0x48310000, ap 76 4e.1 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "rng";
                        reg = <0x11fe0 0x4>,
                              <0x11fe4 0x4>;
                        reg-names = "rev", "sysc";
index fb6b8aa..646f114 100644 (file)
 
                target-module@47810000 {
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmc3";
                        reg = <0x478102fc 0x4>,
                              <0x47810110 0x4>,
                              <0x47810114 0x4>;
                        };
                };
 
-               usb: usb@47400000 {
-                       compatible = "ti,am33xx-usb";
-                       reg = <0x47400000 0x1000>;
-                       ranges;
+               usb: target-module@47400000 {
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x47400000 0x4>,
+                             <0x47400010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP2_SOFTRESET)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       clocks = <&l3s_clkctrl AM3_L3S_USB_OTG_HS_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
                        #size-cells = <1>;
-                       ti,hwmods = "usb_otg_hs";
-                       status = "disabled";
-
-                       usb_ctrl_mod: control@44e10620 {
-                               compatible = "ti,am335x-usb-ctrl-module";
-                               reg = <0x44e10620 0x10
-                                       0x44e10648 0x4>;
-                               reg-names = "phy_ctrl", "wakeup";
-                               status = "disabled";
-                       };
+                       ranges = <0x0 0x47400000 0x5000>;
 
-                       usb0_phy: usb-phy@47401300 {
+                       usb0_phy: usb-phy@1300 {
                                compatible = "ti,am335x-usb-phy";
-                               reg = <0x47401300 0x100>;
+                               reg = <0x1300 0x100>;
                                reg-names = "phy";
-                               status = "disabled";
                                ti,ctrl_mod = <&usb_ctrl_mod>;
                                #phy-cells = <0>;
                        };
 
-                       usb0: usb@47401000 {
+                       usb0: usb@1400 {
                                compatible = "ti,musb-am33xx";
-                               status = "disabled";
-                               reg = <0x47401400 0x400
-                                       0x47401000 0x200>;
+                               reg = <0x1400 0x400>,
+                                     <0x1000 0x200>;
                                reg-names = "mc", "control";
 
                                interrupts = <18>;
                                        "tx14", "tx15";
                        };
 
-                       usb1_phy: usb-phy@47401b00 {
+                       usb1_phy: usb-phy@1b00 {
                                compatible = "ti,am335x-usb-phy";
-                               reg = <0x47401b00 0x100>;
+                               reg = <0x1b00 0x100>;
                                reg-names = "phy";
-                               status = "disabled";
                                ti,ctrl_mod = <&usb_ctrl_mod>;
                                #phy-cells = <0>;
                        };
 
-                       usb1: usb@47401800 {
+                       usb1: usb@1800 {
                                compatible = "ti,musb-am33xx";
-                               status = "disabled";
-                               reg = <0x47401c00 0x400
-                                       0x47401800 0x200>;
+                               reg = <0x1c00 0x400>,
+                                     <0x1800 0x200>;
                                reg-names = "mc", "control";
                                interrupts = <19>;
                                interrupt-names = "mc";
                                        "tx14", "tx15";
                        };
 
-                       cppi41dma: dma-controller@47402000 {
+                       cppi41dma: dma-controller@2000 {
                                compatible = "ti,am3359-cppi41";
-                               reg =  <0x47400000 0x1000
-                                       0x47402000 0x1000
-                                       0x47403000 0x1000
-                                       0x47404000 0x4000>;
+                               reg =  <0x0000 0x1000>,
+                                      <0x2000 0x1000>,
+                                      <0x3000 0x1000>,
+                                      <0x4000 0x4000>;
                                reg-names = "glue", "controller", "scheduler", "queuemgr";
                                interrupts = <17>;
                                interrupt-names = "glue";
                                #dma-cells = <2>;
                                #dma-channels = <30>;
                                #dma-requests = <256>;
-                               status = "disabled";
                        };
                };
 
-               ocmcram: ocmcram@40300000 {
+               ocmcram: sram@40300000 {
                        compatible = "mmio-sram";
                        reg = <0x40300000 0x10000>; /* 64k */
                        ranges = <0x0 0x40300000 0x10000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
 
-                       pm_sram_code: pm-sram-code@0 {
+                       pm_sram_code: pm-code-sram@0 {
                                compatible = "ti,sram";
                                reg = <0x0 0x1000>;
                                protect-exec;
                        };
 
-                       pm_sram_data: pm-sram-data@1000 {
+                       pm_sram_data: pm-data-sram@1000 {
                                compatible = "ti,sram";
                                reg = <0x1000 0x1000>;
                                pool;
 
 #include "am33xx-l4.dtsi"
 #include "am33xx-clocks.dtsi"
+
+&prcm {
+       prm_per: prm@c00 {
+               compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
+               reg = <0xc00 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_wkup: prm@d00 {
+               compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
+               reg = <0xd00 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_device: prm@f00 {
+               compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
+               reg = <0xf00 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_gfx: prm@1100 {
+               compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1100 0x100>;
+               #reset-cells = <1>;
+       };
+};
index 76f819f..125379e 100644 (file)
        };
 };
 
+/* Not currently working, probably needs at least different clocks */
+&rng_target {
+       status = "disabled";
+       /delete-property/ clocks;
+};
+
 /* Table Table 5-79 of the TRM shows 480ab000 is reserved */
 &usb_otg_hs {
        status = "disabled";
index 14bbc43..ca0aa3f 100644 (file)
 
                target-module@47810000 {
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmc3";
                        reg = <0x478102fc 0x4>,
                              <0x47810110 0x4>,
                              <0x47810114 0x4>;
                        };
                };
 
-               ocmcram: ocmcram@40300000 {
+               ocmcram: sram@40300000 {
                        compatible = "mmio-sram";
                        reg = <0x40300000 0x40000>; /* 256k */
                        ranges = <0x0 0x40300000 0x40000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
 
-                       pm_sram_code: pm-sram-code@0 {
+                       pm_sram_code: pm-code-sram@0 {
                                compatible = "ti,sram";
                                reg = <0x0 0x1000>;
                                protect-exec;
                        };
 
-                       pm_sram_data: pm-sram-data@1000 {
+                       pm_sram_data: pm-data-sram@1000 {
                                compatible = "ti,sram";
                                reg = <0x1000 0x1000>;
                                pool;
 
 #include "am437x-l4.dtsi"
 #include "am43xx-clocks.dtsi"
+
+&prcm {
+       prm_gfx: prm@400 {
+               compatible = "ti,am4-prm-inst", "ti,omap-prm-inst";
+               reg = <0x400 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_per: prm@800 {
+               compatible = "ti,am4-prm-inst", "ti,omap-prm-inst";
+               reg = <0x800 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_wkup: prm@2000 {
+               compatible = "ti,am4-prm-inst", "ti,omap-prm-inst";
+               reg = <0x2000 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_device: prm@4000 {
+               compatible = "ti,am4-prm-inst", "ti,omap-prm-inst";
+               reg = <0x4000 0x100>;
+               #reset-cells = <1>;
+       };
+};
index cae4500..811c8ca 100644 (file)
@@ -86,7 +86,7 @@
                };
 
        lcd0: display {
-               compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
+               compatible = "osddisplays,osd070t1718-19ts", "panel-dpi";
                label = "lcd";
 
                backlight = <&lcd_bl>;
index 59770dd..0dd59ee 100644 (file)
 
                target-module@7000 {                    /* 0x44e07000, ap 14 20.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio1";
                        reg = <0x7000 0x4>,
                              <0x7010 0x4>,
                              <0x7114 0x4>;
 
                target-module@9000 {                    /* 0x44e09000, ap 16 04.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart1";
                        reg = <0x9050 0x4>,
                              <0x9054 0x4>,
                              <0x9058 0x4>;
 
                target-module@b000 {                    /* 0x44e0b000, ap 18 48.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c1";
                        reg = <0xb000 0x8>,
                              <0xb010 0x8>,
                              <0xb090 0x8>;
 
                target-module@35000 {                   /* 0x44e35000, ap 28 50.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "wd_timer2";
                        reg = <0x35000 0x4>,
                              <0x35010 0x4>,
                              <0x35014 0x4>;
 
                target-module@22000 {                   /* 0x48022000, ap 8 0a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart2";
                        reg = <0x22050 0x4>,
                              <0x22054 0x4>,
                              <0x22058 0x4>;
 
                target-module@24000 {                   /* 0x48024000, ap 10 1c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart3";
                        reg = <0x24050 0x4>,
                              <0x24054 0x4>,
                              <0x24058 0x4>;
 
                target-module@2a000 {                   /* 0x4802a000, ap 12 22.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c2";
                        reg = <0x2a000 0x8>,
                              <0x2a010 0x8>,
                              <0x2a090 0x8>;
 
                target-module@38000 {                   /* 0x48038000, ap 14 04.0 */
                        compatible = "ti,sysc-omap4-simple", "ti,sysc";
-                       ti,hwmods = "mcasp0";
                        reg = <0x38000 0x4>,
                              <0x38004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3c000 {                   /* 0x4803c000, ap 16 2a.0 */
                        compatible = "ti,sysc-omap4-simple", "ti,sysc";
-                       ti,hwmods = "mcasp1";
                        reg = <0x3c000 0x4>,
                              <0x3c004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@4c000 {                   /* 0x4804c000, ap 28 36.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio2";
                        reg = <0x4c000 0x4>,
                              <0x4c010 0x4>,
                              <0x4c114 0x4>;
 
                target-module@60000 {                   /* 0x48060000, ap 30 14.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmc1";
                        reg = <0x602fc 0x4>,
                              <0x60110 0x4>,
                              <0x60114 0x4>;
 
                target-module@c8000 {                   /* 0x480c8000, ap 73 06.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox";
                        reg = <0xc8000 0x4>,
                              <0xc8010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@9c000 {                   /* 0x4819c000, ap 38 52.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c3";
                        reg = <0x9c000 0x8>,
                              <0x9c010 0x8>,
                              <0x9c090 0x8>;
 
                target-module@a6000 {                   /* 0x481a6000, ap 40 16.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart4";
                        reg = <0xa6050 0x4>,
                              <0xa6054 0x4>,
                              <0xa6058 0x4>;
 
                target-module@a8000 {                   /* 0x481a8000, ap 42 20.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart5";
                        reg = <0xa8050 0x4>,
                              <0xa8054 0x4>,
                              <0xa8058 0x4>;
 
                target-module@aa000 {                   /* 0x481aa000, ap 44 12.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart6";
                        reg = <0xaa050 0x4>,
                              <0xaa054 0x4>,
                              <0xaa058 0x4>;
 
                target-module@ac000 {                   /* 0x481ac000, ap 46 30.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio3";
                        reg = <0xac000 0x4>,
                              <0xac010 0x4>,
                              <0xac114 0x4>;
 
                target-module@ae000 {                   /* 0x481ae000, ap 48 32.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio4";
                        reg = <0xae000 0x4>,
                              <0xae010 0x4>,
                              <0xae114 0x4>;
 
                target-module@d8000 {                   /* 0x481d8000, ap 54 5e.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmc2";
                        reg = <0xd82fc 0x4>,
                              <0xd8110 0x4>,
                              <0xd8114 0x4>;
 
                target-module@10000 {                   /* 0x48310000, ap 64 4e.1 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "rng";
                        reg = <0x11fe0 0x4>,
                              <0x11fe4 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@20000 {                   /* 0x48320000, ap 82 34.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio5";
                        reg = <0x20000 0x4>,
                              <0x20010 0x4>,
                              <0x20114 0x4>;
 
                target-module@22000 {                   /* 0x48322000, ap 116 64.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio6";
                        reg = <0x22000 0x4>,
                              <0x22010 0x4>,
                              <0x22114 0x4>;
 
                target-module@47000 {                   /* 0x48347000, ap 110 70.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "hdq1w";
                        reg = <0x47000 0x4>,
                              <0x47014 0x4>,
                              <0x47018 0x4>;
index 9531412..078cb47 100644 (file)
@@ -42,7 +42,7 @@
        };
 
        lcd0: display {
-               compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
+               compatible = "osddisplays,osd070t1718-19ts", "panel-dpi";
                label = "lcd";
 
                backlight = <&lcd_bl>;
index 7b113b5..39d1c4f 100644 (file)
@@ -24,7 +24,7 @@
 };
 
 &mmc2 {
-       pinctrl-names = "default", "hs", "ddr_1_8v";
+       pinctrl-names = "default", "hs", "ddr_3_3v";
        pinctrl-0 = <&mmc2_pins_default>;
        pinctrl-1 = <&mmc2_pins_hs>;
        pinctrl-2 = <&mmc2_pins_ddr_3_3v_rev11 &mmc2_iodelay_ddr_3_3v_rev11_conf>;
index 30c500b..4187a97 100644 (file)
@@ -24,7 +24,7 @@
 };
 
 &mmc2 {
-       pinctrl-names = "default", "hs", "ddr_1_8v";
+       pinctrl-names = "default", "hs", "ddr_3_3v";
        pinctrl-0 = <&mmc2_pins_default>;
        pinctrl-1 = <&mmc2_pins_hs>;
        pinctrl-2 = <&mmc2_pins_ddr_rev20>;
index 3f4bb44..e038abc 100644 (file)
                        #size-cells = <1>;
                        ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
 
+                       sdramc: sdramc@1400 {
+                               compatible = "marvell,armada-xp-sdram-controller";
+                               reg = <0x1400 0x500>;
+                       };
+
                        L2: cache-controller@8000 {
                                compatible = "arm,pl310-cache";
                                reg = <0x8000 0x1000>;
index 267d0c1..654648b 100644 (file)
@@ -90,7 +90,7 @@
                };
 
                internal-regs {
-                       sdramc@1400 {
+                       sdramc: sdramc@1400 {
                                compatible = "marvell,armada-xp-sdram-controller";
                                reg = <0x1400 0x500>;
                        };
index df04805..4ec0ae0 100644 (file)
        };
 };
 
+&L2 {
+       arm,parity-enable;
+       marvell,ecc-enable;
+};
+
 &devbus_bootcs {
        status = "okay";
 
index ee15c77..6c19984 100644 (file)
@@ -36,7 +36,7 @@
                };
 
                internal-regs {
-                       sdramc@1400 {
+                       sdramc: sdramc@1400 {
                                compatible = "marvell,armada-xp-sdram-controller";
                                reg = <0x1400 0x500>;
                        };
index c9d88c9..8bec21e 100644 (file)
@@ -40,6 +40,7 @@
                status = "okay";
                m25p,fast-read;
                label = "bmc";
+               spi-max-frequency = <50000000>;
 #include "openbmc-flash-layout.dtsi"
        };
 };
@@ -50,6 +51,7 @@
                status = "okay";
                m25p,fast-read;
                label = "pnor";
+               spi-max-frequency = <100000000>;
        };
 };
 
index 9870553..4afa866 100644 (file)
@@ -55,6 +55,9 @@
 
        phy-mode = "rgmii";
        phy-handle = <&ethphy1>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii2_default>;
 };
 
 &mac2 {
@@ -62,6 +65,9 @@
 
        phy-mode = "rgmii";
        phy-handle = <&ethphy2>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii3_default>;
 };
 
 &mac3 {
 
        phy-mode = "rgmii";
        phy-handle = <&ethphy3>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii4_default>;
 };
 
-&emmc {
+&emmc_controller {
        status = "okay";
 };
 
+&emmc {
+       non-removable;
+       bus-width = <4>;
+       max-frequency = <52000000>;
+};
+
 &rtc {
        status = "okay";
 };
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "bmc";
+               spi-max-frequency = <50000000>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       u-boot@0 {
+                               reg = <0x0 0xe0000>; // 896KB
+                               label = "u-boot";
+                       };
+
+                       u-boot-env@e0000 {
+                               reg = <0xe0000 0x20000>; // 128KB
+                               label = "u-boot-env";
+                       };
+
+                       kernel@100000 {
+                               reg = <0x100000 0x900000>; // 9MB
+                               label = "kernel";
+                       };
+
+                       rofs@a00000 {
+                               reg = <0xa00000 0x2000000>; // 32MB
+                               label = "rofs";
+                       };
+
+                       rwfs@6000000 {
+                               reg = <0x2a00000 0x1600000>; // 22MB
+                               label = "rwfs";
+                       };
+               };
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi1_default>;
+
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "pnor";
+               spi-max-frequency = <100000000>;
+       };
+};
+
+&uart5 {
+       // Workaround for A0
+       compatible = "snps,dw-apb-uart";
+};
+
+&i2c0 {
+       status = "okay";
+
+       temp@2e {
+               compatible = "adi,adt7490";
+               reg = <0x2e>;
+       };
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&i2c6 {
+       status = "okay";
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2c8 {
+       status = "okay";
+};
+
+&i2c9 {
+       status = "okay";
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&i2c14 {
+       status = "okay";
+};
+
+&i2c15 {
+       status = "okay";
+};
index 521afbe..2c29ac0 100644 (file)
@@ -92,6 +92,9 @@
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii2_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC2CLK>,
+                <&syscon ASPEED_CLK_MAC2RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index d519d30..016bbcb 100644 (file)
@@ -2,7 +2,7 @@
 // Copyright (c) 2018 Facebook Inc.
 /dts-v1/;
 
-#include "aspeed-g5.dtsi"
+#include "ast2500-facebook-netbmc-common.dtsi"
 
 / {
        model = "Facebook Backpack CMM BMC";
                bootargs = "console=ttyS1,9600n8 root=/dev/ram rw earlyprintk";
        };
 
-       memory@80000000 {
-               reg = <0x80000000 0x20000000>;
-       };
-
        ast-adc-hwmon {
                compatible = "iio-hwmon";
                io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
        };
 };
 
-&pinctrl {
-       aspeed,external-nodes = <&gfx &lhc>;
-};
-
-/*
- * Update reset type to "system" (full chip) to fix warm reboot hang issue
- * when reset type is set to default ("soc", gated by reset mask registers).
- */
-&wdt1 {
-       status = "okay";
-       aspeed,reset-type = "system";
-};
-
-/*
- * wdt2 is not used by Backpack CMM.
- */
-&wdt2 {
-       status = "disabled";
-};
-
-&fmc {
-       status = "okay";
-       flash@0 {
-               status = "okay";
-               m25p,fast-read;
-               label = "bmc";
-#include "facebook-bmc-flash-layout.dtsi"
-       };
-};
-
 &uart1 {
-       status = "okay";
-       pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_txd1_default
                     &pinctrl_rxd1_default
                     &pinctrl_ncts1_default
 };
 
 &uart3 {
-       status = "okay";
-       pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_txd3_default
                     &pinctrl_rxd3_default
                     &pinctrl_ncts3_default
                     &pinctrl_rxd4_default>;
 };
 
-&uart5 {
-       status = "okay";
-};
-
-&mac1 {
-       status = "okay";
-       no-hw-checksum;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
-};
-
 /*
  * I2C bus reserved for communication with COM-E.
  */
 &ehci1 {
        status = "okay";
 };
+
+&vhub {
+       status = "disabled";
+};
+
+&sdhci0 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sd1_default>;
+};
+
+&sdhci1 {
+       status = "disabled";
+};
index c054782..88ce4ff 100644 (file)
@@ -2,7 +2,7 @@
 // Copyright (c) 2018 Facebook Inc.
 /dts-v1/;
 
-#include "aspeed-g5.dtsi"
+#include "ast2500-facebook-netbmc-common.dtsi"
 
 / {
        model = "Facebook Minipack 100 BMC";
                stdout-path = &uart1;
                bootargs = "debug console=ttyS1,9600n8 root=/dev/ram rw";
        };
-
-       memory@80000000 {
-               reg = <0x80000000 0x20000000>;
-       };
 };
 
-&wdt1 {
+&wdt2 {
        status = "okay";
        aspeed,reset-type = "system";
 };
 
-&wdt2 {
-       status = "okay";
-       aspeed,reset-type = "system";
+/*
+ * Both firmware flashes are 64MB on Minipack BMC.
+ */
+&fmc_flash0 {
+       partitions {
+               data0@1c00000 {
+                       reg = <0x1c00000 0x2400000>;
+               };
+               flash0@0 {
+                       reg = <0x0 0x4000000>;
+               };
+       };
 };
 
-&fmc {
-       status = "okay";
-       flash@0 {
-               status = "okay";
-               m25p,fast-read;
-               label = "bmc";
-#include "facebook-bmc-flash-layout.dtsi"
+&fmc_flash1 {
+       partitions {
+               flash1@0 {
+                       reg = <0x0 0x4000000>;
+               };
        };
 };
 
 &uart1 {
-       status = "okay";
-       pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_txd1_default
                     &pinctrl_rxd1_default
                     &pinctrl_ncts1_default
                     &pinctrl_rxd2_default>;
 };
 
-&uart3 {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_txd3_default
-                    &pinctrl_rxd3_default>;
-};
-
 &uart4 {
        status = "okay";
        pinctrl-names = "default";
                     &pinctrl_rxd4_default>;
 };
 
-&uart5 {
-       status = "okay";
-};
-
-&mac1 {
-       status = "okay";
-       no-hw-checksum;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
-};
-
 &i2c0 {
        status = "okay";
        bus-frequency = <400000>;
 &i2c13 {
        status = "okay";
 };
-
-&vhub {
-       status = "okay";
-};
index 682f729..5d7cbd9 100644 (file)
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index 4e09a9c..5293359 100644 (file)
@@ -2,7 +2,7 @@
 // Copyright (c) 2018 Facebook Inc.
 /dts-v1/;
 
-#include "aspeed-g5.dtsi"
+#include "ast2500-facebook-netbmc-common.dtsi"
 
 / {
        model = "Facebook YAMP 100 BMC";
                stdout-path = &uart5;
                bootargs = "console=ttyS0,9600n8 root=/dev/ram rw";
        };
-
-       memory@80000000 {
-               reg = <0x80000000 0x20000000>;
-       };
-};
-
-&pinctrl {
-       aspeed,external-nodes = <&gfx &lhc>;
-};
-
-/*
- * Update reset type to "system" (full chip) to fix warm reboot hang issue
- * when reset type is set to default ("soc", gated by reset mask registers).
- */
-&wdt1 {
-       status = "okay";
-       aspeed,reset-type = "system";
-};
-
-/*
- * wdt2 is not used by Yamp.
- */
-&wdt2 {
-       status = "disabled";
-};
-
-&fmc {
-       status = "okay";
-       flash@0 {
-               status = "okay";
-               m25p,fast-read;
-               label = "bmc";
-#include "facebook-bmc-flash-layout.dtsi"
-       };
-};
-
-&uart1 {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_txd1_default
-                    &pinctrl_rxd1_default>;
 };
 
 &uart2 {
                     &pinctrl_rxd2_default>;
 };
 
-&uart3 {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_txd3_default
-                    &pinctrl_rxd3_default>;
-};
-
-&uart5 {
-       status = "okay";
-};
-
 &mac0 {
        status = "okay";
        use-ncsi;
        no-hw-checksum;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
+};
+
+&mac1 {
+       status = "disabled";
 };
 
 &i2c0 {
 &i2c13 {
        status = "okay";
 };
-
-&vhub {
-       status = "okay";
-};
diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
new file mode 100644 (file)
index 0000000..c1c9cd3
--- /dev/null
@@ -0,0 +1,972 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2019 IBM Corp.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+       model = "Rainier";
+       compatible = "ibm,rainier-bmc", "aspeed,ast2600";
+
+       aliases {
+               serial4 = &uart5;
+       };
+
+       chosen {
+               stdout-path = &uart5;
+               bootargs = "console=ttyS4,115200n8";
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>;
+       };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               flash_memory: region@B8000000 {
+                       no-map;
+                       reg = <0xB8000000 0x04000000>; /* 64M */
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               ps0-presence {
+                       label = "ps0-presence";
+                       gpios = <&gpio0 ASPEED_GPIO(S, 0) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(S, 0)>;
+               };
+
+               ps1-presence {
+                       label = "ps1-presence";
+                       gpios = <&gpio0 ASPEED_GPIO(S, 1) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(S, 1)>;
+               };
+
+               ps2-presence {
+                       label = "ps2-presence";
+                       gpios = <&gpio0 ASPEED_GPIO(S, 2) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(S, 2)>;
+               };
+
+               ps3-presence {
+                       label = "ps3-presence";
+                       gpios = <&gpio0 ASPEED_GPIO(S, 3) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(S, 3)>;
+               };
+       };
+
+};
+
+&emmc_controller {
+       status = "okay";
+};
+
+&emmc {
+       status = "okay";
+};
+
+&ibt {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+
+       power-supply@68 {
+               compatible = "ibm,cffps2";
+               reg = <0x68>;
+       };
+
+       power-supply@69 {
+               compatible = "ibm,cffps2";
+               reg = <0x69>;
+       };
+
+       power-supply@6a {
+               compatible = "ibm,cffps2";
+               reg = <0x6a>;
+       };
+
+       power-supply@6b {
+               compatible = "ibm,cffps2";
+               reg = <0x6b>;
+       };
+};
+
+&i2c4 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@49 {
+               compatible = "ti,tmp275";
+               reg = <0x49>;
+       };
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+
+       eeprom@52 {
+               compatible = "atmel,24c64";
+               reg = <0x52>;
+       };
+};
+
+&i2c5 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@49 {
+               compatible = "ti,tmp275";
+               reg = <0x49>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+};
+
+&i2c6 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+
+       tmp275@4b {
+               compatible = "ti,tmp275";
+               reg = <0x4b>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+
+       eeprom@52 {
+               compatible = "atmel,24c64";
+               reg = <0x52>;
+       };
+
+       eeprom@53 {
+               compatible = "atmel,24c64";
+               reg = <0x53>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+
+       si7021-a20@20 {
+               compatible = "silabs,si7020";
+               reg = <0x20>;
+       };
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       max31785@52 {
+               compatible = "maxim,max31785a";
+               reg = <0x52>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fan@0 {
+                       compatible = "pmbus-fan";
+                       reg = <0>;
+                       tach-pulses = <2>;
+               };
+
+               fan@1 {
+                       compatible = "pmbus-fan";
+                       reg = <1>;
+                       tach-pulses = <2>;
+               };
+
+               fan@2 {
+                       compatible = "pmbus-fan";
+                       reg = <2>;
+                       tach-pulses = <2>;
+               };
+
+               fan@3 {
+                       compatible = "pmbus-fan";
+                       reg = <3>;
+                       tach-pulses = <2>;
+               };
+       };
+
+       pca0: pca9552@60 {
+               compatible = "nxp,pca9552";
+               reg = <0x60>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio@0 {
+                       reg = <0>;
+               };
+
+               gpio@1 {
+                       reg = <1>;
+               };
+
+               gpio@2 {
+                       reg = <2>;
+               };
+
+               gpio@3 {
+                       reg = <3>;
+               };
+
+               gpio@4 {
+                       reg = <4>;
+               };
+
+               gpio@5 {
+                       reg = <5>;
+               };
+
+               gpio@6 {
+                       reg = <6>;
+               };
+
+               gpio@7 {
+                       reg = <7>;
+               };
+
+               gpio@8 {
+                       reg = <8>;
+               };
+
+               gpio@9 {
+                       reg = <9>;
+               };
+
+               gpio@10 {
+                       reg = <10>;
+               };
+
+               gpio@11 {
+                       reg = <11>;
+               };
+
+               gpio@12 {
+                       reg = <12>;
+               };
+
+               gpio@13 {
+                       reg = <13>;
+               };
+
+               gpio@14 {
+                       reg = <14>;
+               };
+
+               gpio@15 {
+                       reg = <15>;
+               };
+       };
+
+       dps: dps310@76 {
+               compatible = "infineon,dps310";
+               reg = <0x76>;
+               #io-channel-cells = <0>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+};
+
+&i2c8 {
+       status = "okay";
+
+       ucd90320@b {
+               compatible = "ti,ucd90160";
+               reg = <0x0b>;
+       };
+
+       ucd90320@c {
+               compatible = "ti,ucd90160";
+               reg = <0x0c>;
+       };
+
+       ucd90320@11 {
+               compatible = "ti,ucd90160";
+               reg = <0x11>;
+       };
+
+       rtc@32 {
+               compatible = "epson,rx8900";
+               reg = <0x32>;
+       };
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+};
+
+&i2c9 {
+       status = "okay";
+
+       ir35221@42 {
+               compatible = "infineon,ir35221";
+               reg = <0x42>;
+       };
+
+       ir35221@43 {
+               compatible = "infineon,ir35221";
+               reg = <0x43>;
+       };
+
+       ir35221@44 {
+               compatible = "infineon,ir35221";
+               reg = <0x44>;
+       };
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       tmp423b@4d {
+               compatible = "ti,tmp423";
+               reg = <0x4d>;
+       };
+
+       ir35221@72 {
+               compatible = "infineon,ir35221";
+               reg = <0x72>;
+       };
+
+       ir35221@73 {
+               compatible = "infineon,ir35221";
+               reg = <0x73>;
+       };
+
+       ir35221@74 {
+               compatible = "infineon,ir35221";
+               reg = <0x74>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c128";
+               reg = <0x50>;
+       };
+};
+
+&i2c10 {
+       status = "okay";
+
+       ir35221@42 {
+               compatible = "infineon,ir35221";
+               reg = <0x42>;
+       };
+
+       ir35221@43 {
+               compatible = "infineon,ir35221";
+               reg = <0x43>;
+       };
+
+       ir35221@44 {
+               compatible = "infineon,ir35221";
+               reg = <0x44>;
+       };
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       tmp423b@4d {
+               compatible = "ti,tmp423";
+               reg = <0x4d>;
+       };
+
+       ir35221@72 {
+               compatible = "infineon,ir35221";
+               reg = <0x72>;
+       };
+
+       ir35221@73 {
+               compatible = "infineon,ir35221";
+               reg = <0x73>;
+       };
+
+       ir35221@74 {
+               compatible = "infineon,ir35221";
+               reg = <0x74>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c128";
+               reg = <0x50>;
+       };
+};
+
+&i2c11 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@49 {
+               compatible = "ti,tmp275";
+               reg = <0x49>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&i2c14 {
+       status = "okay";
+};
+
+&i2c15 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+
+       power-supply@68 {
+               compatible = "ibm,cffps2";
+               reg = <0x68>;
+       };
+
+       power-supply@69 {
+               compatible = "ibm,cffps2";
+               reg = <0x69>;
+       };
+
+       power-supply@6a {
+               compatible = "ibm,cffps2";
+               reg = <0x6a>;
+       };
+
+       power-supply@6b {
+               compatible = "ibm,cffps2";
+               reg = <0x6b>;
+       };
+};
+
+&i2c4 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@49 {
+               compatible = "ti,tmp275";
+               reg = <0x49>;
+       };
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+};
+
+&i2c5 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@49 {
+               compatible = "ti,tmp275";
+               reg = <0x49>;
+       };
+};
+
+&i2c6 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+
+       tmp275@4b {
+               compatible = "ti,tmp275";
+               reg = <0x4b>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+
+       si7021-a20@20 {
+               compatible = "silabs,si7020";
+               reg = <0x20>;
+       };
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       max31785@52 {
+               compatible = "maxim,max31785a";
+               reg = <0x52>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fan@0 {
+                       compatible = "pmbus-fan";
+                       reg = <0>;
+                       tach-pulses = <2>;
+               };
+
+               fan@1 {
+                       compatible = "pmbus-fan";
+                       reg = <1>;
+                       tach-pulses = <2>;
+               };
+
+               fan@2 {
+                       compatible = "pmbus-fan";
+                       reg = <2>;
+                       tach-pulses = <2>;
+               };
+
+               fan@3 {
+                       compatible = "pmbus-fan";
+                       reg = <3>;
+                       tach-pulses = <2>;
+               };
+       };
+
+       pca0: pca9552@60 {
+               compatible = "nxp,pca9552";
+               reg = <0x60>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio@0 {
+                       reg = <0>;
+               };
+
+               gpio@1 {
+                       reg = <1>;
+               };
+
+               gpio@2 {
+                       reg = <2>;
+               };
+
+               gpio@3 {
+                       reg = <3>;
+               };
+
+               gpio@4 {
+                       reg = <4>;
+               };
+
+               gpio@5 {
+                       reg = <5>;
+               };
+
+               gpio@6 {
+                       reg = <6>;
+               };
+
+               gpio@7 {
+                       reg = <7>;
+               };
+
+               gpio@8 {
+                       reg = <8>;
+               };
+
+               gpio@9 {
+                       reg = <9>;
+               };
+
+               gpio@10 {
+                       reg = <10>;
+               };
+
+               gpio@11 {
+                       reg = <11>;
+               };
+
+               gpio@12 {
+                       reg = <12>;
+               };
+
+               gpio@13 {
+                       reg = <13>;
+               };
+
+               gpio@14 {
+                       reg = <14>;
+               };
+
+               gpio@15 {
+                       reg = <15>;
+               };
+       };
+
+       dps: dps310@76 {
+               compatible = "infineon,dps310";
+               reg = <0x76>;
+               #io-channel-cells = <0>;
+       };
+};
+
+&i2c8 {
+       status = "okay";
+
+       ucd90320@b {
+               compatible = "ti,ucd90160";
+               reg = <0x0b>;
+       };
+
+       ucd90320@c {
+               compatible = "ti,ucd90160";
+               reg = <0x0c>;
+       };
+
+       ucd90320@11 {
+               compatible = "ti,ucd90160";
+               reg = <0x11>;
+       };
+
+       rtc@32 {
+               compatible = "epson,rx8900";
+               reg = <0x32>;
+       };
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+};
+
+&i2c9 {
+       status = "okay";
+
+       ir35221@42 {
+               compatible = "infineon,ir35221";
+               reg = <0x42>;
+       };
+
+       ir35221@43 {
+               compatible = "infineon,ir35221";
+               reg = <0x43>;
+       };
+
+       ir35221@44 {
+               compatible = "infineon,ir35221";
+               reg = <0x44>;
+       };
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       tmp423b@4d {
+               compatible = "ti,tmp423";
+               reg = <0x4d>;
+       };
+
+       ir35221@72 {
+               compatible = "infineon,ir35221";
+               reg = <0x72>;
+       };
+
+       ir35221@73 {
+               compatible = "infineon,ir35221";
+               reg = <0x73>;
+       };
+
+       ir35221@74 {
+               compatible = "infineon,ir35221";
+               reg = <0x74>;
+       };
+};
+
+&i2c10 {
+       status = "okay";
+
+       ir35221@42 {
+               compatible = "infineon,ir35221";
+               reg = <0x42>;
+       };
+
+       ir35221@43 {
+               compatible = "infineon,ir35221";
+               reg = <0x43>;
+       };
+
+       ir35221@44 {
+               compatible = "infineon,ir35221";
+               reg = <0x44>;
+       };
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       tmp423b@4d {
+               compatible = "ti,tmp423";
+               reg = <0x4d>;
+       };
+
+       ir35221@72 {
+               compatible = "infineon,ir35221";
+               reg = <0x72>;
+       };
+
+       ir35221@73 {
+               compatible = "infineon,ir35221";
+               reg = <0x73>;
+       };
+
+       ir35221@74 {
+               compatible = "infineon,ir35221";
+               reg = <0x74>;
+       };
+};
+
+&i2c11 {
+       status = "okay";
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@49 {
+               compatible = "ti,tmp275";
+               reg = <0x49>;
+       };
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+};
+
+&i2c14 {
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+};
+
+&i2c15 {
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+};
+
+&vuart1 {
+       status = "okay";
+};
+
+&lpc_ctrl {
+       status = "okay";
+       memory-region = <&flash_memory>;
+};
+
+&mac2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rmii3_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC3CLK>,
+                <&syscon ASPEED_CLK_MAC3RCLK>;
+       clock-names = "MACCLK", "RCLK";
+       use-ncsi;
+};
+
+&mac3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rmii4_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC4CLK>,
+                <&syscon ASPEED_CLK_MAC4RCLK>;
+       clock-names = "MACCLK", "RCLK";
+       use-ncsi;
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "bmc";
+               spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+       };
+
+       flash@1 {
+               status = "okay";
+               m25p,fast-read;
+               label = "alt-bmc";
+               spi-max-frequency = <50000000>;
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi1_default>;
+
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "pnor";
+               spi-max-frequency = <100000000>;
+       };
+};
index e9d714a..c17bb7f 100644 (file)
        };
 
        leds {
-           compatible = "gpio-leds";
+               compatible = "gpio-leds";
 
-           power {
-                   label = "power";
-                   /* TODO: dummy gpio */
-                   gpios = <&gpio ASPEED_GPIO(R, 1) GPIO_ACTIVE_LOW>;
-           };
+               power {
+                       label = "power";
+                       /* TODO: dummy gpio */
+                       gpios = <&gpio ASPEED_GPIO(R, 1) GPIO_ACTIVE_LOW>;
+               };
+
+               init-ok {
+                       label = "init-ok";
+                       gpios = <&gpio ASPEED_GPIO(B, 7) GPIO_ACTIVE_LOW>;
+               };
+
+               front-memory {
+                       label = "front-memory";
+                       gpios = <&gpio ASPEED_GPIO(F, 4) GPIO_ACTIVE_LOW>;
+               };
+
+               front-syshot {
+                       label = "front-syshot";
+                       gpios = <&gpio ASPEED_GPIO(I, 1) GPIO_ACTIVE_LOW>;
+               };
+
+               front-syshealth {
+                       label = "front-syshealth";
+                       gpios = <&gpio ASPEED_GPIO(I, 0) GPIO_ACTIVE_LOW>;
+               };
 
+               front-fan {
+                       label = "front-fan";
+                       gpios = <&gpio ASPEED_GPIO(H, 4) GPIO_ACTIVE_LOW>;
+               };
+
+               front-psu {
+                       label = "front-psu";
+                       gpios = <&gpio ASPEED_GPIO(B, 2) GPIO_ACTIVE_LOW>;
+               };
+
+               identify {
+                       label = "identify";
+                       gpios = <&gpio ASPEED_GPIO(Z, 7) GPIO_ACTIVE_LOW>;
+               };
        };
 
        iio-hwmon-battery {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
        aspeed,external-nodes = <&gfx &lhc>;
 };
 
-&gpio {
-       pin_gpio_b7 {
-               gpio-hog;
-               gpios = <ASPEED_GPIO(B,7) GPIO_ACTIVE_LOW>;
-               output-high;
-               line-name = "BMC_INIT_OK";
-       };
-};
-
 &wdt1 {
        aspeed,reset-type = "none";
        aspeed,external-signal;
index 2337ee2..80c92e0 100644 (file)
@@ -77,6 +77,9 @@
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index 22dade6..1deb30e 100644 (file)
@@ -69,6 +69,9 @@
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index d3695a3..c29e5f4 100644 (file)
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index 118eb8b..084c455 100644 (file)
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index de95112..42b37a2 100644 (file)
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index e55cc45..f7e935e 100644 (file)
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index b0cb34c..eb4e93a 100644 (file)
@@ -87,6 +87,7 @@
                status = "okay";
                m25p,fast-read;
                label = "bmc";
+               spi-max-frequency = <50000000>;
 #include "openbmc-flash-layout.dtsi"
        };
 };
        flash@0 {
                status = "okay";
                m25p,fast-read;
+               spi-max-frequency = <50000000>;
                label = "pnor";
        };
 };
index 9628ecb..edfa44f 100644 (file)
                status = "okay";
                m25p,fast-read;
                label = "bmc";
+               spi-max-frequency = <50000000>;
 #include "openbmc-flash-layout.dtsi"
        };
 };
                status = "okay";
                m25p,fast-read;
                label = "pnor";
+               spi-max-frequency = <100000000>;
        };
 };
 
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
 };
 
 &i2c1 {
index f67fef1..b8fdd2a 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
        use-ncsi;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
 };
 
 &i2c2 {
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
new file mode 100644 (file)
index 0000000..f02de4a
--- /dev/null
@@ -0,0 +1,1195 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2019 IBM Corp.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/leds/leds-pca955x.h>
+
+/ {
+       model = "Tacoma";
+       compatible = "ibm,tacoma-bmc", "aspeed,ast2600";
+
+       chosen {
+               stdout-path = &uart5;
+               bootargs = "console=ttyS4,115200n8";
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>;
+       };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               flash_memory: region@ba000000 {
+                       no-map;
+                       reg = <0xb8000000 0x4000000>; /* 64M */
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               air-water {
+                       label = "air-water";
+                       gpios = <&gpio0 ASPEED_GPIO(Q, 7) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(Q, 7)>;
+               };
+
+               checkstop {
+                       label = "checkstop";
+                       gpios = <&gpio0 ASPEED_GPIO(E, 3) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(E, 3)>;
+               };
+
+               ps0-presence {
+                       label = "ps0-presence";
+                       gpios = <&gpio0 ASPEED_GPIO(H, 3) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(H, 3)>;
+               };
+
+               ps1-presence {
+                       label = "ps1-presence";
+                       gpios = <&gpio0 ASPEED_GPIO(E, 5) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(E, 5)>;
+               };
+       };
+
+       gpio-keys-polled {
+               compatible = "gpio-keys-polled";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               poll-interval = <1000>;
+
+               fan0-presence {
+                       label = "fan0-presence";
+                       gpios = <&pca0 4 GPIO_ACTIVE_LOW>;
+                       linux,code = <4>;
+               };
+
+               fan1-presence {
+                       label = "fan1-presence";
+                       gpios = <&pca0 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <5>;
+               };
+
+               fan2-presence {
+                       label = "fan2-presence";
+                       gpios = <&pca0 6 GPIO_ACTIVE_LOW>;
+                       linux,code = <6>;
+               };
+
+               fan3-presence {
+                       label = "fan3-presence";
+                       gpios = <&pca0 7 GPIO_ACTIVE_LOW>;
+                       linux,code = <7>;
+               };
+       };
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "bmc";
+               spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+       };
+
+       flash@1 {
+               status = "okay";
+               m25p,fast-read;
+               label = "alt-bmc";
+               spi-max-frequency = <50000000>;
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi1_default>;
+
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "pnor";
+               spi-max-frequency = <100000000>;
+       };
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "bmc";
+               spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+       };
+
+       flash@1 {
+               status = "okay";
+               m25p,fast-read;
+               label = "alt-bmc";
+               spi-max-frequency = <50000000>;
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi1_default>;
+
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "pnor";
+               spi-max-frequency = <100000000>;
+       };
+};
+
+&mac2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rmii3_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC3CLK>,
+                <&syscon ASPEED_CLK_MAC3RCLK>;
+       clock-names = "MACCLK", "RCLK";
+       use-ncsi;
+};
+
+&emmc {
+       status = "okay";
+       #address-cells = <2>;
+       #size-cells = <0>;
+
+       cfam@0,0 {
+               reg = <0 0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               chip-id = <0>;
+
+               scom@1000 {
+                       compatible = "ibm,fsi2pib";
+                       reg = <0x1000 0x400>;
+               };
+
+               i2c@1800 {
+                       compatible = "ibm,fsi-i2c-master";
+                       reg = <0x1800 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       cfam0_i2c0: i2c-bus@0 {
+                               reg = <0>;
+                       };
+
+                       cfam0_i2c1: i2c-bus@1 {
+                               reg = <1>;
+                       };
+
+                       cfam0_i2c2: i2c-bus@2 {
+                               reg = <2>;
+                       };
+
+                       cfam0_i2c3: i2c-bus@3 {
+                               reg = <3>;
+                       };
+
+                       cfam0_i2c4: i2c-bus@4 {
+                               reg = <4>;
+                       };
+
+                       cfam0_i2c5: i2c-bus@5 {
+                               reg = <5>;
+                       };
+
+                       cfam0_i2c6: i2c-bus@6 {
+                               reg = <6>;
+                       };
+
+                       cfam0_i2c7: i2c-bus@7 {
+                               reg = <7>;
+                       };
+
+                       cfam0_i2c8: i2c-bus@8 {
+                               reg = <8>;
+                       };
+
+                       cfam0_i2c9: i2c-bus@9 {
+                               reg = <9>;
+                       };
+
+                       cfam0_i2c10: i2c-bus@a {
+                               reg = <10>;
+                       };
+
+                       cfam0_i2c11: i2c-bus@b {
+                               reg = <11>;
+                       };
+
+                       cfam0_i2c12: i2c-bus@c {
+                               reg = <12>;
+                       };
+
+                       cfam0_i2c13: i2c-bus@d {
+                               reg = <13>;
+                       };
+
+                       cfam0_i2c14: i2c-bus@e {
+                               reg = <14>;
+                       };
+               };
+
+               sbefifo@2400 {
+                       compatible = "ibm,p9-sbefifo";
+                       reg = <0x2400 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       fsi_occ0: occ {
+                               compatible = "ibm,p9-occ";
+                       };
+               };
+
+               fsi_hub0: hub@3400 {
+                       compatible = "fsi-master-hub";
+                       reg = <0x3400 0x400>;
+                       #address-cells = <2>;
+                       #size-cells = <0>;
+
+                       no-scan-on-init;
+               };
+       };
+};
+
+&fsi_hub0 {
+       cfam@1,0 {
+               reg = <1 0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               chip-id = <1>;
+
+               scom@1000 {
+                       compatible = "ibm,fsi2pib";
+                       reg = <0x1000 0x400>;
+               };
+
+               i2c@1800 {
+                       compatible = "ibm,fsi-i2c-master";
+                       reg = <0x1800 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       cfam1_i2c0: i2c-bus@0 {
+                               reg = <0>;
+                       };
+
+                       cfam1_i2c1: i2c-bus@1 {
+                               reg = <1>;
+                       };
+
+                       cfam1_i2c2: i2c-bus@2 {
+                               reg = <2>;
+                       };
+
+                       cfam1_i2c3: i2c-bus@3 {
+                               reg = <3>;
+                       };
+
+                       cfam1_i2c4: i2c-bus@4 {
+                               reg = <4>;
+                       };
+
+                       cfam1_i2c5: i2c-bus@5 {
+                               reg = <5>;
+                       };
+
+                       cfam1_i2c6: i2c-bus@6 {
+                               reg = <6>;
+                       };
+
+                       cfam1_i2c7: i2c-bus@7 {
+                               reg = <7>;
+                       };
+
+                       cfam1_i2c8: i2c-bus@8 {
+                               reg = <8>;
+                       };
+
+                       cfam1_i2c9: i2c-bus@9 {
+                               reg = <9>;
+                       };
+
+                       cfam1_i2c10: i2c-bus@a {
+                               reg = <10>;
+                       };
+
+                       cfam1_i2c11: i2c-bus@b {
+                               reg = <11>;
+                       };
+
+                       cfam1_i2c12: i2c-bus@c {
+                               reg = <12>;
+                       };
+
+                       cfam1_i2c13: i2c-bus@d {
+                               reg = <13>;
+                       };
+
+                       cfam1_i2c14: i2c-bus@e {
+                               reg = <14>;
+                       };
+               };
+
+               sbefifo@2400 {
+                       compatible = "ibm,p9-sbefifo";
+                       reg = <0x2400 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       fsi_occ1: occ {
+                               compatible = "ibm,p9-occ";
+                       };
+               };
+
+               fsi_hub1: hub@3400 {
+                       compatible = "fsi-master-hub";
+                       reg = <0x3400 0x400>;
+                       #address-cells = <2>;
+                       #size-cells = <0>;
+
+                       no-scan-on-init;
+               };
+       };
+};
+
+/* Legacy OCC numbering (to get rid of when userspace is fixed) */
+&fsi_occ0 {
+       reg = <1>;
+};
+
+&fsi_occ1 {
+       reg = <2>;
+};
+
+/ {
+       aliases {
+               i2c100 = &cfam0_i2c0;
+               i2c101 = &cfam0_i2c1;
+               i2c102 = &cfam0_i2c2;
+               i2c103 = &cfam0_i2c3;
+               i2c104 = &cfam0_i2c4;
+               i2c105 = &cfam0_i2c5;
+               i2c106 = &cfam0_i2c6;
+               i2c107 = &cfam0_i2c7;
+               i2c108 = &cfam0_i2c8;
+               i2c109 = &cfam0_i2c9;
+               i2c110 = &cfam0_i2c10;
+               i2c111 = &cfam0_i2c11;
+               i2c112 = &cfam0_i2c12;
+               i2c113 = &cfam0_i2c13;
+               i2c114 = &cfam0_i2c14;
+               i2c200 = &cfam1_i2c0;
+               i2c201 = &cfam1_i2c1;
+               i2c202 = &cfam1_i2c2;
+               i2c203 = &cfam1_i2c3;
+               i2c204 = &cfam1_i2c4;
+               i2c205 = &cfam1_i2c5;
+               i2c206 = &cfam1_i2c6;
+               i2c207 = &cfam1_i2c7;
+               i2c208 = &cfam1_i2c8;
+               i2c209 = &cfam1_i2c9;
+               i2c210 = &cfam1_i2c10;
+               i2c211 = &cfam1_i2c11;
+               i2c212 = &cfam1_i2c12;
+               i2c213 = &cfam1_i2c13;
+               i2c214 = &cfam1_i2c14;
+       };
+
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+
+       bmp: bmp280@77 {
+               compatible = "bosch,bmp280";
+               reg = <0x77>;
+               #io-channel-cells = <1>;
+       };
+
+       max31785@52 {
+               compatible = "maxim,max31785a";
+               reg = <0x52>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fan@0 {
+                       compatible = "pmbus-fan";
+                       reg = <0>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+
+               fan@1 {
+                       compatible = "pmbus-fan";
+                       reg = <1>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+
+               fan@2 {
+                       compatible = "pmbus-fan";
+                       reg = <2>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+
+               fan@3 {
+                       compatible = "pmbus-fan";
+                       reg = <3>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+       };
+
+       dps: dps310@76 {
+               compatible = "infineon,dps310";
+               reg = <0x76>;
+               #io-channel-cells = <0>;
+       };
+
+       pca0: pca9552@60 {
+               compatible = "nxp,pca9552";
+               reg = <0x60>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio@0 {
+                       reg = <0>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@1 {
+                       reg = <1>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@2 {
+                       reg = <2>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@3 {
+                       reg = <3>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@4 {
+                       reg = <4>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@5 {
+                       reg = <5>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@6 {
+                       reg = <6>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@7 {
+                       reg = <7>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@8 {
+                       reg = <8>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@9 {
+                       reg = <9>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@10 {
+                       reg = <10>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@11 {
+                       reg = <11>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@12 {
+                       reg = <12>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@13 {
+                       reg = <13>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@14 {
+                       reg = <14>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@15 {
+                       reg = <15>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+       };
+
+       power-supply@68 {
+               compatible = "ibm,cffps1";
+               reg = <0x68>;
+       };
+
+       power-supply@69 {
+               compatible = "ibm,cffps1";
+               reg = <0x69>;
+       };
+};
+
+&i2c4 {
+       status = "okay";
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       ir35221@70 {
+               compatible = "infineon,ir35221";
+               reg = <0x70>;
+       };
+
+       ir35221@71 {
+               compatible = "infineon,ir35221";
+               reg = <0x71>;
+       };
+};
+
+&i2c5 {
+       status = "okay";
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       ir35221@70 {
+               compatible = "infineon,ir35221";
+               reg = <0x70>;
+       };
+
+       ir35221@71 {
+               compatible = "infineon,ir35221";
+               reg = <0x71>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2c9 {
+       status = "okay";
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+};
+
+&i2c10 {
+       status = "okay";
+};
+
+&i2c11 {
+       status = "okay";
+
+       pca9552: pca9552@60 {
+               compatible = "nxp,pca9552";
+               reg = <0x60>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio-line-names = "PS_SMBUS_RESET_N", "APSS_RESET_N",
+                       "GPU0_TH_OVERT_N_BUFF", "GPU1_TH_OVERT_N_BUFF",
+                       "GPU2_TH_OVERT_N_BUFF", "GPU3_TH_OVERT_N_BUFF",
+                       "GPU4_TH_OVERT_N_BUFF", "GPU5_TH_OVERT_N_BUFF",
+                       "GPU0_PWR_GOOD_BUFF", "GPU1_PWR_GOOD_BUFF",
+                       "GPU2_PWR_GOOD_BUFF", "GPU3_PWR_GOOD_BUFF",
+                       "GPU4_PWR_GOOD_BUFF", "GPU5_PWR_GOOD_BUFF",
+                       "12V_BREAKER_FLT_N", "THROTTLE_UNLATCHED_N";
+
+               gpio@0 {
+                       reg = <0>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@1 {
+                       reg = <1>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@2 {
+                       reg = <2>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@3 {
+                       reg = <3>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@4 {
+                       reg = <4>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@5 {
+                       reg = <5>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@6 {
+                       reg = <6>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@7 {
+                       reg = <7>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@8 {
+                       reg = <8>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@9 {
+                       reg = <9>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@10 {
+                       reg = <10>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@11 {
+                       reg = <11>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@12 {
+                       reg = <12>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@13 {
+                       reg = <13>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@14 {
+                       reg = <14>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@15 {
+                       reg = <15>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+       };
+
+       rtc@32 {
+               compatible = "epson,rx8900";
+               reg = <0x32>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+
+       ucd90160@64 {
+               compatible = "ti,ucd90160";
+               reg = <0x64>;
+       };
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&ibt {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+       // Workaround for A0
+       compatible = "snps,dw-apb-uart";
+};
+
+&uart5 {
+       // Workaround for A0
+       compatible = "snps,dw-apb-uart";
+};
+
+&vuart1 {
+       status = "okay";
+};
+
+&lpc_ctrl {
+       status = "okay";
+       memory-region = <&flash_memory>;
+       flash = <&spi1>;
+};
+
+&wdt1 {
+       aspeed,reset-type = "none";
+       aspeed,external-signal;
+       aspeed,ext-push-pull;
+       aspeed,ext-active-high;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdtrst1_default>;
+};
+
+&wdt2 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+
+       bmp: bmp280@77 {
+               compatible = "bosch,bmp280";
+               reg = <0x77>;
+               #io-channel-cells = <1>;
+       };
+
+       max31785@52 {
+               compatible = "maxim,max31785a";
+               reg = <0x52>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fan@0 {
+                       compatible = "pmbus-fan";
+                       reg = <0>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+
+               fan@1 {
+                       compatible = "pmbus-fan";
+                       reg = <1>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+
+               fan@2 {
+                       compatible = "pmbus-fan";
+                       reg = <2>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+
+               fan@3 {
+                       compatible = "pmbus-fan";
+                       reg = <3>;
+                       tach-pulses = <2>;
+                       maxim,fan-rotor-input = "tach";
+                       maxim,fan-pwm-freq = <25000>;
+                       maxim,fan-dual-tach;
+                       maxim,fan-no-watchdog;
+                       maxim,fan-no-fault-ramp;
+                       maxim,fan-ramp = <2>;
+                       maxim,fan-fault-pin-mon;
+               };
+       };
+
+       dps: dps310@76 {
+               compatible = "infineon,dps310";
+               reg = <0x76>;
+               #io-channel-cells = <0>;
+       };
+
+       pca0: pca9552@60 {
+               compatible = "nxp,pca9552";
+               reg = <0x60>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio@0 {
+                       reg = <0>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@1 {
+                       reg = <1>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@2 {
+                       reg = <2>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@3 {
+                       reg = <3>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@4 {
+                       reg = <4>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@5 {
+                       reg = <5>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@6 {
+                       reg = <6>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@7 {
+                       reg = <7>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@8 {
+                       reg = <8>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@9 {
+                       reg = <9>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@10 {
+                       reg = <10>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@11 {
+                       reg = <11>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@12 {
+                       reg = <12>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@13 {
+                       reg = <13>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@14 {
+                       reg = <14>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@15 {
+                       reg = <15>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+       };
+
+       power-supply@68 {
+               compatible = "ibm,cffps1";
+               reg = <0x68>;
+       };
+
+       power-supply@69 {
+               compatible = "ibm,cffps1";
+               reg = <0x69>;
+       };
+};
+
+&i2c4 {
+       status = "okay";
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       ir35221@70 {
+               compatible = "infineon,ir35221";
+               reg = <0x70>;
+       };
+
+       ir35221@71 {
+               compatible = "infineon,ir35221";
+               reg = <0x71>;
+       };
+};
+
+&i2c5 {
+       status = "okay";
+
+       tmp423a@4c {
+               compatible = "ti,tmp423";
+               reg = <0x4c>;
+       };
+
+       ir35221@70 {
+               compatible = "infineon,ir35221";
+               reg = <0x70>;
+       };
+
+       ir35221@71 {
+               compatible = "infineon,ir35221";
+               reg = <0x71>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2c9 {
+       status = "okay";
+
+       tmp275@4a {
+               compatible = "ti,tmp275";
+               reg = <0x4a>;
+       };
+};
+
+&i2c10 {
+       status = "okay";
+};
+
+&i2c11 {
+       status = "okay";
+
+       pca9552: pca9552@60 {
+               compatible = "nxp,pca9552";
+               reg = <0x60>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio-line-names = "PS_SMBUS_RESET_N", "APSS_RESET_N",
+                       "GPU0_TH_OVERT_N_BUFF", "GPU1_TH_OVERT_N_BUFF",
+                       "GPU2_TH_OVERT_N_BUFF", "GPU3_TH_OVERT_N_BUFF",
+                       "GPU4_TH_OVERT_N_BUFF", "GPU5_TH_OVERT_N_BUFF",
+                       "GPU0_PWR_GOOD_BUFF", "GPU1_PWR_GOOD_BUFF",
+                       "GPU2_PWR_GOOD_BUFF", "GPU3_PWR_GOOD_BUFF",
+                       "GPU4_PWR_GOOD_BUFF", "GPU5_PWR_GOOD_BUFF",
+                       "12V_BREAKER_FLT_N", "THROTTLE_UNLATCHED_N";
+
+               gpio@0 {
+                       reg = <0>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@1 {
+                       reg = <1>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@2 {
+                       reg = <2>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@3 {
+                       reg = <3>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@4 {
+                       reg = <4>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@5 {
+                       reg = <5>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@6 {
+                       reg = <6>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@7 {
+                       reg = <7>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@8 {
+                       reg = <8>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@9 {
+                       reg = <9>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@10 {
+                       reg = <10>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@11 {
+                       reg = <11>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@12 {
+                       reg = <12>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@13 {
+                       reg = <13>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@14 {
+                       reg = <14>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+               gpio@15 {
+                       reg = <15>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+       };
+
+       rtc@32 {
+               compatible = "epson,rx8900";
+               reg = <0x32>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c64";
+               reg = <0x51>;
+       };
+
+       ucd90160@64 {
+               compatible = "ti,ucd90160";
+               reg = <0x64>;
+       };
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&pinctrl {
+       /* Hog these as no driver is probed for the entire LPC block */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpc_default>,
+                   <&pinctrl_lsirq_default>;
+};
index a27c88d..affd2c8 100644 (file)
                        gpios = <&gpio ASPEED_GPIO(N, 1) GPIO_ACTIVE_LOW>;
                };
 
+               power_green {
+                       gpios = <&gpio ASPEED_GPIO(F, 1) GPIO_ACTIVE_LOW>;
+               };
+
                id_blue {
                        gpios = <&gpio ASPEED_GPIO(O, 0) GPIO_ACTIVE_LOW>;
                };
index 31ea34e..569dad9 100644 (file)
                status = "okay";
                label = "bmc";
                m25p,fast-read;
+               spi-max-frequency = <50000000>;
 
                partitions {
                        #address-cells = < 1 >;
                status = "okay";
                label = "alt-bmc";
                m25p,fast-read;
+               spi-max-frequency = <50000000>;
 
                partitions {
                        #address-cells = < 1 >;
                                label = "alt-obmc-ubi";
                        };
                };
-
        };
 };
 
                status = "okay";
                label = "pnor";
                m25p,fast-read;
+               spi-max-frequency = <100000000>;
        };
 };
 
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index 3062437..bc60ec2 100644 (file)
                status = "okay";
                label = "bmc";
                m25p,fast-read;
+               spi-max-frequency = <50000000>;
 #include "openbmc-flash-layout.dtsi"
        };
 };
                status = "okay";
                label = "pnor";
                m25p,fast-read;
+               spi-max-frequency = <100000000>;
        };
 };
 
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index 33d7045..4a1ca8f 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default
                     &pinctrl_mdio1_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+                <&syscon ASPEED_CLK_MAC1RCLK>;
+       clock-names = "MACCLK", "RCLK";
 };
 
 &mac1 {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii2_default>;
+       clocks = <&syscon ASPEED_CLK_GATE_MAC2CLK>,
+                <&syscon ASPEED_CLK_MAC2RCLK>;
+       clock-names = "MACCLK", "RCLK";
        use-ncsi;
 };
 
index dffb595..46c0891 100644 (file)
@@ -65,6 +65,7 @@
                        flash@0 {
                                reg = < 0 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                        flash@1 {
                        flash@0 {
                                reg = < 0 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                };
                                #reset-cells = <1>;
 
                                pinctrl: pinctrl {
-                                       compatible = "aspeed,g4-pinctrl";
+                                       compatible = "aspeed,ast2400-pinctrl";
                                };
 
                                p2a: p2a-control {
index f56b8d1..a259c63 100644 (file)
                        flash@0 {
                                reg = < 0 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                        flash@1 {
                                reg = < 1 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                        flash@2 {
                                reg = < 2 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                };
                        flash@0 {
                                reg = < 0 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                        flash@1 {
                                reg = < 1 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                };
                        flash@0 {
                                reg = < 0 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                        flash@1 {
                                reg = < 1 >;
                                compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
                };
                                #reset-cells = <1>;
 
                                pinctrl: pinctrl {
-                                       compatible = "aspeed,g5-pinctrl";
+                                       compatible = "aspeed,ast2500-pinctrl";
                                        aspeed,external-nodes = <&gfx &lhc>;
 
                                };
                                #gpio-cells = <2>;
                                gpio-controller;
                                compatible = "aspeed,ast2500-gpio";
-                               reg = <0x1e780000 0x1000>;
+                               reg = <0x1e780000 0x200>;
                                interrupts = <20>;
                                gpio-ranges = <&pinctrl 0 0 232>;
                                clocks = <&syscon ASPEED_CLK_APB>;
                                #interrupt-cells = <2>;
                        };
 
+                       sgpio: sgpio@1e780200 {
+                               #gpio-cells = <2>;
+                               compatible = "aspeed,ast2500-sgpio";
+                               gpio-controller;
+                               interrupts = <40>;
+                               reg = <0x1e780200 0x0100>;
+                               clocks = <&syscon ASPEED_CLK_APB>;
+                               interrupt-controller;
+                               ngpios = <8>;
+                               bus-frequency = <12000000>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_sgpm_default>;
+                               status = "disabled";
+                       };
+
                        rtc: rtc@1e781000 {
                                compatible = "aspeed,ast2500-rtc";
                                reg = <0x1e781000 0x18>;
index 5b8bf58..045ce66 100644 (file)
                groups = "SD2";
        };
 
-       pinctrl_sd3_default: sd3_default {
-               function = "SD3";
-               groups = "SD3";
-       };
-
        pinctrl_emmc_default: emmc_default {
-               function = "SD3";
-               groups = "EMMC";
+               function = "EMMC";
+               groups = "EMMCG4";
        };
 
        pinctrl_sgpm1_default: sgpm1_default {
index 3a1422f..5f6142d 100644 (file)
        interrupt-parent = <&gic>;
 
        aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+               i2c6 = &i2c6;
+               i2c7 = &i2c7;
+               i2c8 = &i2c8;
+               i2c9 = &i2c9;
+               i2c10 = &i2c10;
+               i2c11 = &i2c11;
+               i2c12 = &i2c12;
+               i2c13 = &i2c13;
+               i2c14 = &i2c14;
+               i2c15 = &i2c15;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
                serial4 = &uart5;
+               serial5 = &vuart1;
+               serial6 = &vuart2;
        };
 
 
                            <0x40466000 0x2000>;
                        };
 
+               fmc: spi@1e620000 {
+                       reg = < 0x1e620000 0xc4
+                               0x20000000 0x10000000 >;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "aspeed,ast2600-fmc";
+                       clocks = <&syscon ASPEED_CLK_AHB>;
+                       status = "disabled";
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+                       flash@0 {
+                               reg = < 0 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+                       flash@1 {
+                               reg = < 1 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+                       flash@2 {
+                               reg = < 2 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+               };
+
+               spi1: spi@1e630000 {
+                       reg = < 0x1e630000 0xc4
+                               0x30000000 0x10000000 >;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "aspeed,ast2600-spi";
+                       clocks = <&syscon ASPEED_CLK_AHB>;
+                       status = "disabled";
+                       flash@0 {
+                               reg = < 0 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+                       flash@1 {
+                               reg = < 1 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+               };
+
+               spi2: spi@1e631000 {
+                       reg = < 0x1e631000 0xc4
+                               0x50000000 0x10000000 >;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "aspeed,ast2600-spi";
+                       clocks = <&syscon ASPEED_CLK_AHB>;
+                       status = "disabled";
+                       flash@0 {
+                               reg = < 0 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+                       flash@1 {
+                               reg = < 1 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+                       flash@2 {
+                               reg = < 2 >;
+                               compatible = "jedec,spi-nor";
+                               spi-max-frequency = <50000000>;
+                               status = "disabled";
+                       };
+
+                       fsim0: fsi@1e79b000 {
+                               compatible = "aspeed,ast2600-fsi-master", "fsi-master";
+                               reg = <0x1e79b000 0x94>;
+                               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_fsi1_default>;
+                               clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
+                               status = "disabled";
+                       };
+
+                       fsim1: fsi@1e79b100 {
+                               compatible = "aspeed,ast2600-fsi-master", "fsi-master";
+                               reg = <0x1e79b100 0x94>;
+                               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_fsi2_default>;
+                               clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
+                               status = "disabled";
+                       };
+               };
+
                mdio0: mdio@1e650000 {
                        compatible = "aspeed,ast2600-mdio";
                        reg = <0x1e650000 0x8>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_mdio1_default>;
                };
 
                mdio1: mdio@1e650008 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_mdio2_default>;
                };
 
                mdio2: mdio@1e650010 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_mdio3_default>;
                };
 
                mdio3: mdio@1e650018 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_mdio4_default>;
                };
 
                mac0: ftgmac@1e660000 {
                                quality = <100>;
                        };
 
+                       gpio0: gpio@1e780000 {
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               compatible = "aspeed,ast2600-gpio";
+                               reg = <0x1e780000 0x800>;
+                               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-ranges = <&pinctrl 0 0 208>;
+                               ngpios = <208>;
+                               clocks = <&syscon ASPEED_CLK_APB2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio1: gpio@1e780800 {
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               compatible = "aspeed,ast2600-gpio";
+                               reg = <0x1e780800 0x800>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-ranges = <&pinctrl 0 208 36>;
+                               ngpios = <36>;
+                               clocks = <&syscon ASPEED_CLK_APB1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
                        rtc: rtc@1e781000 {
                                compatible = "aspeed,ast2600-rtc";
                                reg = <0x1e781000 0x18>;
                                status = "disabled";
                        };
 
+                       timer: timer@1e782000 {
+                               compatible = "aspeed,ast2600-timer";
+                               reg = <0x1e782000 0x90>;
+                               interrupts-extended = <&gic  GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                                               <&gic  GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                                               <&gic  GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                                               <&gic  GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                                               <&gic  GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+                                               <&gic  GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+                                               <&gic  GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+                                               <&gic  GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&syscon ASPEED_CLK_APB1>;
+                               clock-names = "PCLK";
+                        };
+
+                       uart1: serial@1e783000 {
+                               compatible = "ns16550a";
+                               reg = <0x1e783000 0x20>;
+                               reg-shift = <2>;
+                               reg-io-width = <4>;
+                               interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&syscon ASPEED_CLK_GATE_UART1CLK>;
+                               resets = <&lpc_reset 4>;
+                               no-loopback-test;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_txd1_default &pinctrl_rxd1_default>;
+                               status = "disabled";
+                       };
+
                        uart5: serial@1e784000 {
                                compatible = "ns16550a";
                                reg = <0x1e784000 0x1000>;
                                status = "disabled";
                        };
 
+                       lpc: lpc@1e789000 {
+                               compatible = "aspeed,ast2600-lpc", "simple-mfd";
+                               reg = <0x1e789000 0x1000>;
+
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0x1e789000 0x1000>;
+
+                               lpc_bmc: lpc-bmc@0 {
+                                       compatible = "aspeed,ast2600-lpc-bmc", "simple-mfd", "syscon";
+                                       reg = <0x0 0x80>;
+                                       reg-io-width = <4>;
+
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       ranges = <0x0 0x0 0x80>;
+
+                                       kcs1: kcs1@0 {
+                                               compatible = "aspeed,ast2600-kcs-bmc";
+                                               interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                                               kcs_chan = <1>;
+                                               status = "disabled";
+                                       };
+                                       kcs2: kcs2@0 {
+                                               compatible = "aspeed,ast2600-kcs-bmc";
+                                               interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+                                               kcs_chan = <2>;
+                                               status = "disabled";
+                                       };
+                                       kcs3: kcs3@0 {
+                                               compatible = "aspeed,ast2600-kcs-bmc";
+                                               interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+                                               kcs_chan = <3>;
+                                               status = "disabled";
+                                       };
+                               };
+
+                               lpc_host: lpc-host@80 {
+                                       compatible = "aspeed,ast2600-lpc-host", "simple-mfd", "syscon";
+                                       reg = <0x80 0x1e0>;
+                                       reg-io-width = <4>;
+
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       ranges = <0x0 0x80 0x1e0>;
+
+                                       kcs4: kcs4@0 {
+                                               compatible = "aspeed,ast2600-kcs-bmc";
+                                               interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+                                               kcs_chan = <4>;
+                                               status = "disabled";
+                                       };
+
+                                       lpc_ctrl: lpc-ctrl@0 {
+                                               compatible = "aspeed,ast2600-lpc-ctrl";
+                                               reg = <0x0 0x80>;
+                                               clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
+                                               status = "disabled";
+                                       };
+
+                                       lpc_snoop: lpc-snoop@0 {
+                                               compatible = "aspeed,ast2600-lpc-snoop";
+                                               reg = <0x0 0x80>;
+                                               interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+                                               status = "disabled";
+                                       };
+
+                                       lhc: lhc@20 {
+                                               compatible = "aspeed,ast2600-lhc";
+                                               reg = <0x20 0x24 0x48 0x8>;
+                                       };
+
+                                       lpc_reset: reset-controller@18 {
+                                               compatible = "aspeed,ast2600-lpc-reset";
+                                               reg = <0x18 0x4>;
+                                               #reset-cells = <1>;
+                                       };
+
+                                       ibt: ibt@c0 {
+                                               compatible = "aspeed,ast2600-ibt-bmc";
+                                               reg = <0xc0 0x18>;
+                                               interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+                                               status = "disabled";
+                                       };
+                               };
+                       };
+
                        sdc: sdc@1e740000 {
                                compatible = "aspeed,ast2600-sd-controller";
                                reg = <0x1e740000 0x100>;
                                };
                        };
 
-                       emmc: sdc@1e750000 {
+                       emmc_controller: sdc@1e750000 {
                                compatible = "aspeed,ast2600-sd-controller";
                                reg = <0x1e750000 0x100>;
                                #address-cells = <1>;
                                clocks = <&syscon ASPEED_CLK_GATE_EMMCCLK>;
                                status = "disabled";
 
-                               sdhci@1e750100 {
+                               emmc: sdhci@1e750100 {
                                        compatible = "aspeed,ast2600-sdhci";
                                        reg = <0x100 0x100>;
                                        sdhci,auto-cmd12;
                                        pinctrl-0 = <&pinctrl_emmc_default>;
                                };
                        };
+
+                       vuart1: serial@1e787000 {
+                               compatible = "aspeed,ast2500-vuart";
+                               reg = <0x1e787000 0x40>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&syscon ASPEED_CLK_APB1>;
+                               no-loopback-test;
+                               status = "disabled";
+                       };
+
+                       vuart2: serial@1e788000 {
+                               compatible = "aspeed,ast2500-vuart";
+                               reg = <0x1e788000 0x40>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&syscon ASPEED_CLK_APB1>;
+                               no-loopback-test;
+                               status = "disabled";
+                       };
+
+                       uart2: serial@1e78d000 {
+                               compatible = "ns16550a";
+                               reg = <0x1e78d000 0x20>;
+                               reg-shift = <2>;
+                               reg-io-width = <4>;
+                               interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&syscon ASPEED_CLK_GATE_UART2CLK>;
+                               resets = <&lpc_reset 5>;
+                               no-loopback-test;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>;
+                               status = "disabled";
+                       };
+
+                       uart3: serial@1e78e000 {
+                               compatible = "ns16550a";
+                               reg = <0x1e78e000 0x20>;
+                               reg-shift = <2>;
+                               reg-io-width = <4>;
+                               interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&syscon ASPEED_CLK_GATE_UART3CLK>;
+                               resets = <&lpc_reset 6>;
+                               no-loopback-test;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_txd3_default &pinctrl_rxd3_default>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@1e78f000 {
+                               compatible = "ns16550a";
+                               reg = <0x1e78f000 0x20>;
+                               reg-shift = <2>;
+                               reg-io-width = <4>;
+                               interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&syscon ASPEED_CLK_GATE_UART4CLK>;
+                               resets = <&lpc_reset 7>;
+                               no-loopback-test;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_txd4_default &pinctrl_rxd4_default>;
+                               status = "disabled";
+                       };
+
+                       i2c: bus@1e78a000 {
+                               compatible = "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x1e78a000 0x1000>;
+                       };
+
                };
        };
 };
 
 #include "aspeed-g6-pinctrl.dtsi"
+
+&i2c {
+       i2c0: i2c-bus@80 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x80 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c1_default>;
+               status = "disabled";
+       };
+
+       i2c1: i2c-bus@100 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x100 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c2_default>;
+               status = "disabled";
+       };
+
+       i2c2: i2c-bus@180 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x180 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c3_default>;
+               status = "disabled";
+       };
+
+       i2c3: i2c-bus@200 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x200 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c4_default>;
+               status = "disabled";
+       };
+
+       i2c4: i2c-bus@280 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x280 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c5_default>;
+               status = "disabled";
+       };
+
+       i2c5: i2c-bus@300 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x300 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c6_default>;
+               status = "disabled";
+       };
+
+       i2c6: i2c-bus@380 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x380 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c7_default>;
+               status = "disabled";
+       };
+
+       i2c7: i2c-bus@400 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x400 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c8_default>;
+               status = "disabled";
+       };
+
+       i2c8: i2c-bus@480 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x480 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c9_default>;
+               status = "disabled";
+       };
+
+       i2c9: i2c-bus@500 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x500 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c10_default>;
+               status = "disabled";
+       };
+
+       i2c10: i2c-bus@580 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x580 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c11_default>;
+               status = "disabled";
+       };
+
+       i2c11: i2c-bus@600 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x600 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c12_default>;
+               status = "disabled";
+       };
+
+       i2c12: i2c-bus@680 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x680 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c13_default>;
+               status = "disabled";
+       };
+
+       i2c13: i2c-bus@700 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x700 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c14_default>;
+               status = "disabled";
+       };
+
+       i2c14: i2c-bus@780 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x780 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c15_default>;
+               status = "disabled";
+       };
+
+       i2c15: i2c-bus@800 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               #interrupt-cells = <1>;
+               reg = <0x800 0x80>;
+               compatible = "aspeed,ast2600-i2c-bus";
+               clocks = <&syscon ASPEED_CLK_APB2>;
+               resets = <&syscon ASPEED_RESET_I2C>;
+               interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+               bus-frequency = <100000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c16_default>;
+               status = "disabled";
+       };
+};
diff --git a/arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi b/arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi
new file mode 100644 (file)
index 0000000..7a395ba
--- /dev/null
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2019 Facebook Inc.
+
+#include "aspeed-g5.dtsi"
+
+/ {
+       memory@80000000 {
+               reg = <0x80000000 0x40000000>;
+       };
+};
+
+/*
+ * Update reset type to "system" (full chip) to fix warm reboot hang issue
+ * when reset type is set to default ("soc", gated by reset mask registers).
+ */
+&wdt1 {
+       status = "okay";
+       aspeed,reset-type = "system";
+};
+
+&wdt2 {
+       status = "disabled";
+};
+
+&uart1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd1_default
+                    &pinctrl_rxd1_default>;
+};
+
+&uart3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd3_default
+                    &pinctrl_rxd3_default>;
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&fmc {
+       status = "okay";
+
+       fmc_flash0: flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "spi0.0";
+
+#include "facebook-bmc-flash-layout.dtsi"
+       };
+
+       fmc_flash1: flash@1 {
+               status = "okay";
+               m25p,fast-read;
+               label = "spi0.1";
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       flash1@0 {
+                               reg = <0x0 0x2000000>;
+                               label = "flash1";
+                       };
+               };
+       };
+};
+
+&mac1 {
+       status = "okay";
+       no-hw-checksum;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&rtc {
+       status = "okay";
+};
+
+&vhub {
+       status = "okay";
+};
+
+&sdmmc {
+       status = "okay";
+};
+
+&sdhci1 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sd2_default>;
+};
diff --git a/arch/arm/boot/dts/at91-kizbox2-2.dts b/arch/arm/boot/dts/at91-kizbox2-2.dts
new file mode 100644 (file)
index 0000000..cab8b35
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-kizbox2-2.dts - Device Tree file for the Kizbox2 with
+ * two head board
+ *
+ * Copyright (C) 2015 Overkiz SAS
+ *
+ * Authors: Antoine Aubert <a.aubert@overkiz.com>
+ *         Kévin Raymond <k.raymond@overkiz.com>
+ */
+/dts-v1/;
+#include "at91-kizbox2-common.dtsi"
+
+/ {
+       model = "Overkiz Kizbox 2 with two heads";
+       compatible = "overkiz,kizbox2-2", "atmel,sama5d31",
+                    "atmel,sama5d3", "atmel,sama5";
+};
+
+&usart1 {
+       status = "okay";
+};
+
+&usart2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/at91-kizbox2-common.dtsi b/arch/arm/boot/dts/at91-kizbox2-common.dtsi
new file mode 100644 (file)
index 0000000..af38253
--- /dev/null
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-kizbox2_common.dtsi - Device Tree Include file for
+ * Overkiz Kizbox 2 family SoC
+ *
+ * Copyright (C) 2014-2018 Overkiz SAS
+ *
+ * Authors: Antoine Aubert <a.aubert@overkiz.com>
+ *          Gaël Portay <g.portay@overkiz.com>
+ *          Kévin Raymond <k.raymond@overkiz.com>
+ */
+#include "sama5d31.dtsi"
+
+/ {
+       chosen {
+               bootargs = "ubi.mtd=ubi";
+               stdout-path = &dbgu;
+       };
+
+       memory {
+               reg = <0x20000000 0x10000000>;
+       };
+
+       clocks {
+               slow_xtal {
+                       clock-frequency = <32768>;
+               };
+
+               main_xtal {
+                       clock-frequency = <12000000>;
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               prog {
+                       label = "PB_PROG";
+                       gpios = <&pioE 27 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x102>;
+                       wakeup-source;
+               };
+
+               reset {
+                       label = "PB_RST";
+                       gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x100>;
+                       wakeup-source;
+               };
+
+               user {
+                       label = "PB_USER";
+                       gpios = <&pioE 31 GPIO_ACTIVE_HIGH>;
+                       linux,code = <0x101>;
+                       wakeup-source;
+               };
+       };
+
+       pwm_leds {
+               compatible = "pwm-leds";
+
+               blue {
+                       label = "pwm:blue:user";
+                       pwms = <&pwm0 2 10000000 0>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "none";
+               };
+
+               green {
+                       label = "pwm:green:user";
+                       pwms = <&pwm0 1 10000000 0>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "default-on";
+               };
+
+               red {
+                       label = "pwm:red:user";
+                       pwms = <&pwm0 0 10000000 0>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "default-on";
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+
+       pmic: act8865@5b {
+               compatible = "active-semi,act8865";
+               reg = <0x5b>;
+               status = "okay";
+
+               regulators {
+                       vcc_1v8_reg: DCDC_REG1 {
+                               regulator-name = "VCC_1V8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_1v2_reg: DCDC_REG2 {
+                               regulator-name = "VCC_1V2";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_3v3_reg: DCDC_REG3 {
+                               regulator-name = "VCC_3V3";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vddfuse_reg: LDO_REG1 {
+                               regulator-name = "FUSE_2V5";
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                       };
+
+                       vddana_reg: LDO_REG2 {
+                               regulator-name = "VDDANA";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vled_reg: LDO_REG3 {
+                               regulator-name = "VLED";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       v3v8_rf_reg: LDO_REG4 {
+                               regulator-name = "V3V8_RF";
+                               regulator-min-microvolt = <3800000>;
+                               regulator-max-microvolt = <3800000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&usart0 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+&usart1 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+&usart2 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+&pwm0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_pwmh0_1
+                    &pinctrl_pwm0_pwmh1_1
+                    &pinctrl_pwm0_pwmh2_0>;
+       status = "okay";
+};
+
+&adc0 {
+       atmel,adc-vref = <3333>;
+       status = "okay";
+};
+
+&macb1 {
+       phy-mode = "rmii";
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+&watchdog {
+       status = "okay";
+};
+
+&ebi {
+       pinctrl-0 = <&pinctrl_ebi_nand_addr>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&nand_controller {
+       status = "okay";
+
+       nand@3 {
+               reg = <0x3 0x0 0x2>;
+               atmel,rb = <0>;
+               nand-bus-width = <8>;
+               nand-ecc-mode = "hw";
+               nand-ecc-strength = <4>;
+               nand-ecc-step-size = <512>;
+               nand-on-flash-bbt;
+               label = "atmel_nand";
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       bootstrap@0 {
+                               label = "bootstrap";
+                               reg = <0x0 0x20000>;
+                       };
+
+                       ubi@20000 {
+                               label = "ubi";
+                               reg = <0x20000 0x7fe0000>;
+                       };
+               };
+       };
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&usb2 {
+       status = "okay";
+};
+
+/* WMBUS (inverted with IO in the latest schematic) */
+&pinctrl_usart0 {
+       atmel,pins =
+               <AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE
+                AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+                AT91_PIOE 2 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+};
+
+/* RTS */
+&pinctrl_usart1 {
+       atmel,pins =
+               <AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE
+                AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+                AT91_PIOE 7 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+};
+
+/* IO (inverted with WMBUS in the latest schematic) */
+&pinctrl_usart2 {
+       atmel,pins =
+               <AT91_PIOE 25 AT91_PERIPH_B AT91_PINCTRL_NONE
+                AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
+                AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+};
diff --git a/arch/arm/boot/dts/at91-kizbox2.dts b/arch/arm/boot/dts/at91-kizbox2.dts
deleted file mode 100644 (file)
index 86d8218..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * at91-kizbox2.dts - Device Tree file for Overkiz Kizbox 2 board
- *
- * Copyright (C) 2014 Gaël PORTAY <g.portay@overkiz.com>
- */
-/dts-v1/;
-#include "sama5d31.dtsi"
-#include <dt-bindings/pwm/pwm.h>
-
-/ {
-       model = "Overkiz Kizbox 2";
-       compatible = "overkiz,kizbox2", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
-
-       chosen {
-               bootargs = "ubi.mtd=ubi";
-               stdout-path = &dbgu;
-       };
-
-       memory {
-               reg = <0x20000000 0x10000000>;
-       };
-
-       clocks {
-               slow_xtal {
-                       clock-frequency = <32768>;
-               };
-
-               main_xtal {
-                       clock-frequency = <12000000>;
-               };
-       };
-
-       ahb {
-               apb {
-                       i2c1: i2c@f0018000 {
-                               status = "okay";
-
-                               pmic: act8865@5b {
-                                       compatible = "active-semi,act8865";
-                                       reg = <0x5b>;
-                                       status = "okay";
-
-                                       regulators {
-                                               vcc_1v8_reg: DCDC_REG1 {
-                                                       regulator-name = "VCC_1V8";
-                                                       regulator-min-microvolt = <1800000>;
-                                                       regulator-max-microvolt = <1800000>;
-                                                       regulator-always-on;
-                                               };
-
-                                               vcc_1v2_reg: DCDC_REG2 {
-                                                       regulator-name = "VCC_1V2";
-                                                       regulator-min-microvolt = <1200000>;
-                                                       regulator-max-microvolt = <1200000>;
-                                                       regulator-always-on;
-                                               };
-
-                                               vcc_3v3_reg: DCDC_REG3 {
-                                                       regulator-name = "VCC_3V3";
-                                                       regulator-min-microvolt = <3300000>;
-                                                       regulator-max-microvolt = <3300000>;
-                                                       regulator-always-on;
-                                               };
-
-                                               vddfuse_reg: LDO_REG1 {
-                                                       regulator-name = "FUSE_2V5";
-                                                       regulator-min-microvolt = <2500000>;
-                                                       regulator-max-microvolt = <2500000>;
-                                               };
-
-                                               vddana_reg: LDO_REG2 {
-                                                       regulator-name = "VDDANA";
-                                                       regulator-min-microvolt = <3300000>;
-                                                       regulator-max-microvolt = <3300000>;
-                                                       regulator-always-on;
-                                               };
-
-                                               vled_reg: LDO_REG3 {
-                                                       regulator-name = "VLED";
-                                                       regulator-min-microvolt = <3300000>;
-                                                       regulator-max-microvolt = <3300000>;
-                                                       regulator-always-on;
-                                               };
-
-                                               v3v8_rf_reg: LDO_REG4 {
-                                                       regulator-name = "V3V8_RF";
-                                                       regulator-min-microvolt = <3800000>;
-                                                       regulator-max-microvolt = <3800000>;
-                                                       regulator-always-on;
-                                               };
-                                       };
-                               };
-                       };
-
-                       tcb0: timer@f0010000 {
-                               timer@0 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <0>;
-                               };
-
-                               timer@1 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <1>;
-                               };
-                       };
-
-                       usart0: serial@f001c000 {
-                               status = "okay";
-                       };
-
-                       usart1: serial@f0020000 {
-                               status = "okay";
-                       };
-
-                       pwm0: pwm@f002c000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_pwm0_pwmh0_1
-                                            &pinctrl_pwm0_pwmh1_1
-                                            &pinctrl_pwm0_pwmh2_0>;
-                               status = "okay";
-                       };
-
-                       adc0: adc@f8018000 {
-                               atmel,adc-vref = <3333>;
-                               status = "okay";
-                       };
-
-                       usart2: serial@f8020000 {
-                               status = "okay";
-                       };
-
-                       macb1: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
-
-                       dbgu: serial@ffffee00 {
-                               status = "okay";
-                       };
-
-                       watchdog@fffffe40 {
-                               status = "okay";
-                       };
-               };
-
-               usb1: ohci@600000 {
-                       status = "okay";
-               };
-
-               usb2: ehci@700000 {
-                       status = "okay";
-               };
-
-               ebi: ebi@10000000 {
-                       pinctrl-0 = <&pinctrl_ebi_nand_addr>;
-                       pinctrl-names = "default";
-                       status = "okay";
-
-                       nand_controller: nand-controller {
-                               status = "okay";
-
-                               nand@3 {
-                                       reg = <0x3 0x0 0x2>;
-                                       atmel,rb = <0>;
-                                       nand-bus-width = <8>;
-                                       nand-ecc-mode = "hw";
-                                       nand-ecc-strength = <4>;
-                                       nand-ecc-step-size = <512>;
-                                       nand-on-flash-bbt;
-                                       label = "atmel_nand";
-
-                                       partitions {
-                                               compatible = "fixed-partitions";
-                                               #address-cells = <1>;
-                                               #size-cells = <1>;
-
-                                               bootstrap@0 {
-                                                       label = "bootstrap";
-                                                       reg = <0x0 0x20000>;
-                                               };
-
-                                               ubi@20000 {
-                                                       label = "ubi";
-                                                       reg = <0x20000 0x7fe0000>;
-                                               };
-                                       };
-                               };
-                       };
-               };
-       };
-
-       gpio_keys {
-               compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               prog {
-                       label = "PB_PROG";
-                       gpios = <&pioE 27 GPIO_ACTIVE_LOW>;
-                       linux,code = <0x102>;
-                       wakeup-source;
-               };
-
-               reset {
-                       label = "PB_RST";
-                       gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
-                       linux,code = <0x100>;
-                       wakeup-source;
-               };
-
-               user {
-                       label = "PB_USER";
-                       gpios = <&pioE 31 GPIO_ACTIVE_HIGH>;
-                       linux,code = <0x101>;
-                       wakeup-source;
-               };
-       };
-
-       pwm_leds {
-               compatible = "pwm-leds";
-
-               blue {
-                       label = "pwm:blue:user";
-                       pwms = <&pwm0 2 10000000 0>;
-                       max-brightness = <255>;
-                       linux,default-trigger = "default-on";
-               };
-
-               green {
-                       label = "pwm:green:user";
-                       pwms = <&pwm0 1 10000000 0>;
-                       max-brightness = <255>;
-                       linux,default-trigger = "default-on";
-               };
-
-               red {
-                       label = "pwm:red:user";
-                       pwms = <&pwm0 0 10000000 0>;
-                       max-brightness = <255>;
-                       linux,default-trigger = "default-on";
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/at91-kizbox3-hs.dts b/arch/arm/boot/dts/at91-kizbox3-hs.dts
new file mode 100644 (file)
index 0000000..8734e7f
--- /dev/null
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-kizbox3-hs.dts - Device Tree file for Overkiz KIZBOX3-HS board
+ *
+ * Copyright (C) 2018 Overkiz SAS
+ *
+ * Authors: Dorian Rocipon <d.rocipon@overkiz.com>
+ *          Kevin Carli <k.carli@overkiz.com>
+ *          Mickael Gardet <m.gardet@overkiz.com>
+ */
+/dts-v1/;
+#include "at91-kizbox3_common.dtsi"
+
+/ {
+       model = "Overkiz KIZBOX3-HS";
+       compatible = "overkiz,kizbox3-hs", "atmel,sama5d2", "atmel,sama5";
+
+       pwm_leds {
+               status = "okay";
+
+               red {
+                       status = "okay";
+               };
+
+               green {
+                       status = "okay";
+               };
+
+               blue {
+                       status = "okay";
+               };
+
+               white {
+                       status = "okay";
+               };
+       };
+
+       leds  {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_led_red
+                            &pinctrl_led_white>;
+               status = "okay";
+
+               red {
+                       label = "pio:red:user";
+                       gpios = <&pioA PIN_PB1 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               white {
+                       label = "pio:white:user";
+                       gpios = <&pioA PIN_PB8 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default" , "default", "default",
+                               "default", "default" ;
+               pinctrl-0 = <&pinctrl_key_gpio_default>;
+               pinctrl-1 = <&pinctrl_pio_rf &pinctrl_pio_wifi>;
+               pinctrl-2 = <&pinctrl_pio_io_boot
+                            &pinctrl_pio_io_reset
+                            &pinctrl_pio_io_test_radio>;
+               pinctrl-3 = <&pinctrl_pio_zbe_test_radio
+                            &pinctrl_pio_zbe_rst>;
+               pinctrl-4 = <&pinctrl_pio_input>;
+
+               SW1 {
+                       label = "SW1";
+                       gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x101>;
+                       wakeup-source;
+               };
+
+               SW2 {
+                       label = "SW2";
+                       gpios = <&pioA PIN_PA18 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x102>;
+                       wakeup-source;
+               };
+
+               SW3 {
+                       label = "SW3";
+                       gpios = <&pioA PIN_PA22 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x103>;
+                       wakeup-source;
+               };
+
+               SW7 {
+                       label = "SW7";
+                       gpios = <&pioA PIN_PA26 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x107>;
+                       wakeup-source;
+               };
+
+               SW8 {
+                       label = "SW8";
+                       gpios = <&pioA PIN_PA24 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x108>;
+                       wakeup-source;
+               };
+       };
+
+       gpios {
+               compatible = "gpio";
+               status = "okay";
+
+               rf_on {
+                       label = "rf on";
+                       gpio = <&pioA PIN_PC19 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               wifi_on {
+                       label = "wifi on";
+                       gpio = <&pioA PIN_PC20 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               zbe_test_radio {
+                       label = "zbe test radio";
+                       gpio = <&pioA PIN_PB21 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               zbe_rst {
+                       label = "zbe rst";
+                       gpio = <&pioA PIN_PB25 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               io_reset {
+                       label = "io reset";
+                       gpio = <&pioA PIN_PB30 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               io_test_radio {
+                       label = "io test radio";
+                       gpio = <&pioA PIN_PC9 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               io_boot_0 {
+                       label = "io boot 0";
+                       gpio = <&pioA PIN_PC11 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               io_boot_1 {
+                       label = "io boot 1";
+                       gpio = <&pioA PIN_PC17 GPIO_ACTIVE_HIGH>;
+                       output;
+                       init-low;
+               };
+
+               verbose_bootloader {
+                       label = "verbose bootloader";
+                       gpio = <&pioA PIN_PB11 GPIO_ACTIVE_HIGH>;
+                       input;
+               };
+
+                nail_bed_detection  {
+                       label = "nail bed detection";
+                       gpio = <&pioA PIN_PB12 GPIO_ACTIVE_HIGH>;
+                       input;
+               };
+
+                id_usba {
+                       label = "id usba";
+                       gpio = <&pioA PIN_PC0 GPIO_ACTIVE_LOW>;
+                       input;
+               };
+       };
+};
+
+&pioA {
+       pinctrl_key_gpio_default: key_gpio_default {
+               pinmux=  <PIN_PA22__GPIO>,
+               <PIN_PA24__GPIO>,
+               <PIN_PA26__GPIO>,
+               <PIN_PA29__GPIO>,
+               <PIN_PA18__GPIO>;
+               bias-disable;
+               };
+
+       pinctrl_gpio {
+               pinctrl_pio_rf: gpio_rf {
+                       pinmux = <PIN_PC19__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_pio_wifi: gpio_wifi {
+                       pinmux = <PIN_PC20__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_pio_io_boot: gpio_io_boot {
+                       pinmux =
+                       <PIN_PC11__GPIO>,
+                       <PIN_PC17__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_pio_io_test_radio: gpio_io_test_radio {
+                       pinmux = <PIN_PC9__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_pio_zbe_test_radio: gpio_zbe_test_radio {
+                       pinmux = <PIN_PB21__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_pio_zbe_rst: gpio_zbe_rst {
+                       pinmux = <PIN_PB25__GPIO>;
+                       bias-disable;
+               };
+               /* stm32 reset must be open drain (internal pull up) */
+               pinctrl_pio_io_reset: gpio_io_reset {
+                       pinmux = <PIN_PB30__GPIO>;
+                       bias-disable;
+                       drive-open-drain = <1>;
+                       output-low;
+               };
+               pinctrl_pio_input: gpio_input {
+                       pinmux =
+                       <PIN_PB11__GPIO>,
+                       <PIN_PB12__GPIO>,
+                       <PIN_PC0__GPIO>;
+                       bias-disable;
+               };
+       };
+
+       pinctrl_leds {
+               pinctrl_led_red: led_red {
+                       pinmux = <PIN_PB1__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_led_white: led_white {
+                       pinmux = <PIN_PB8__GPIO>;
+                       bias-disable;
+               };
+       };
+};
+
+&adc {
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&uart4 {
+       status = "okay";
+};
+
+&flx0 {
+       status = "okay";
+
+       uart5: serial@200  {
+                       status = "okay";
+       };
+};
+
+&flx3 {
+       status = "okay";
+       uart6: serial@200 {
+               status = "okay";
+       };
+};
+
+&flx4 {
+       status = "okay";
+
+       i2c2: i2c@600 {
+               status = "okay";
+       };
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&usb2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/at91-kizbox3_common.dtsi b/arch/arm/boot/dts/at91-kizbox3_common.dtsi
new file mode 100644 (file)
index 0000000..299e74d
--- /dev/null
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-kizbox3.dts - Device Tree Include file for Overkiz Kizbox 3
+ * family SoC boards
+ *
+ * Copyright (C) 2018 Overkiz SAS
+ *
+ * Authors: Dorian Rocipon <d.rocipon@overkiz.com>
+ *          Kevin Carli <k.carli@overkiz.com>
+ *          Mickael Gardet <m.gardet@overkiz.com>
+ */
+/dts-v1/;
+#include "sama5d2.dtsi"
+#include "sama5d2-pinfunc.h"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+       model = "Overkiz Kizbox3";
+       compatible = "overkiz,kizbox3", "atmel,sama5d2", "atmel,sama5";
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+               serial5 = &uart5;
+               serial6 = &uart6;
+       };
+
+       chosen {
+               bootargs = "ubi.mtd=ubi";
+               stdout-path = "serial1:115200n8";
+       };
+
+       clocks {
+               slow_xtal {
+                       clock-frequency = <32768>;
+               };
+
+               main_xtal {
+                       clock-frequency = <12000000>;
+               };
+       };
+
+       vdd_adc_vddana: supply_3v3_ana {
+               compatible = "regulator-fixed";
+               regulator-name = "adc-vddana";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       vdd_adc_vref: supply_3v3_ref {
+               compatible = "regulator-fixed";
+               regulator-name = "adc-vref";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       pwm_leds {
+               compatible = "pwm-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pwm0_pwm_h0
+                            &pinctrl_pwm0_pwm_h1
+                            &pinctrl_pwm0_pwm_h2
+                            &pinctrl_pwm0_pwm_h3>;
+               status = "disabled";
+
+               red {
+                       label = "pwm:red:user";
+                       pwms = <&pwm0 0 10000000 0>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "default-on";
+                       status = "disabled";
+               };
+
+               green {
+                       label = "pwm:green:user";
+                       pwms = <&pwm0 1 10000000 0>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "default-on";
+                       status = "disabled";
+               };
+
+               blue {
+                       label = "pwm:blue:user";
+                       pwms = <&pwm0 2 10000000 0>;
+                       max-brightness = <255>;
+                       status = "disabled";
+               };
+
+               white {
+                       label = "pwm:white:user";
+                       pwms = <&pwm0 3 10000000 0>;
+                       max-brightness = <255>;
+                       status = "disabled";
+               };
+       };
+};
+
+&ebi {
+       status = "okay";
+};
+
+&nand_controller {
+       status = "okay";
+
+       nand@3 {
+               pinctrl-0 = <&pinctrl_ebi_nand_addr>;
+               pinctrl-names = "default";
+               reg = <0x3 0x0 0x800000>;
+
+               atmel,rb = <0>;
+               nand-bus-width = <8>;
+               nand-ecc-mode = "hw";
+               nand-ecc-strength = <4>;
+               nand-ecc-step-size = <512>;
+               nand-on-flash-bbt;
+               label = "atmel_nand";
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       bootstrap@0 {
+                               label = "bootstrap";
+                               reg = <0x0 0x20000>;
+                       };
+
+                       u-boot@20000 {
+                               label = "u-boot";
+                               reg = <0x20000 0x140000>;
+                       };
+
+                       u-boot-factory@160000 {
+                               label = "u-boot-factory";
+                               reg = <0x160000 0x140000>;
+                       };
+
+                       ubi@2A0000 {
+                               label = "ubi";
+                               reg = <0x2A0000 0x7D60000>;
+                       };
+               };
+
+       };
+};
+
+&rtc {
+       status = "okay";
+};
+
+&pioA {
+       pinctrl_ebi_nand_addr: ebi-addr-1 {
+               pinmux = <PIN_PA0__D0>,
+                       <PIN_PA1__D1>,
+                       <PIN_PA2__D2>,
+                       <PIN_PA3__D3>,
+                       <PIN_PA4__D4>,
+                       <PIN_PA5__D5>,
+                       <PIN_PA6__D6>,
+                       <PIN_PA7__D7>,
+                       <PIN_PA8__NWE_NANDWE>,
+                       <PIN_PA9__NCS3>,
+                       <PIN_PA10__A21_NANDALE>,
+                       <PIN_PA11__A22_NANDCLE>,
+                       <PIN_PA21__NANDRDY>;
+               bias-disable;
+       };
+
+       pinctrl_usart {
+               pinctrl_usart_0: usart0-0 {
+                       pinmux = < PIN_PB26__URXD0>, <PIN_PB27__UTXD0>;
+                       bias-disable;
+               };
+               pinctrl_usart_1: usart1-0 {
+                       pinmux = < PIN_PD2__URXD1>, <PIN_PD3__UTXD1>;
+                       bias-disable;
+               };
+               pinctrl_usart_2: usart2-0 {
+                       pinmux = < PIN_PD4__URXD2>, <PIN_PD5__UTXD2>;
+                       bias-disable;
+               };
+               pinctrl_usart_3: usart3-0 {
+                       pinmux = < PIN_PC12__URXD3>, <PIN_PC13__UTXD3>;
+                       bias-disable;
+               };
+               pinctrl_usart_4: usart4-0 {
+                       pinmux = < PIN_PB3__URXD4>, <PIN_PB4__UTXD4>;
+                       bias-disable;
+               };
+               pinctrl_flx0_default: flx0_usart_default {
+                       pinmux = <PIN_PB28__FLEXCOM0_IO0>, //TX
+                       <PIN_PB29__FLEXCOM0_IO1>; //RX
+                       bias-disable;
+               };
+               pinctrl_flx3_default: flx3_usart_default {
+                       pinmux = <PIN_PB22__FLEXCOM3_IO1>, //RX
+                       <PIN_PB23__FLEXCOM3_IO0>; //TX
+                       bias-disable;
+               };
+       };
+
+       pinctrl_flx4_default: flx4_i2c2_default {
+               pinmux = <PIN_PD12__FLEXCOM4_IO0>, //DATA
+               <PIN_PD13__FLEXCOM4_IO1>; //CLK
+               bias-disable;
+               drive-open-drain = <1>;
+       };
+
+       pinctrl_pwm0 {
+               pinctrl_pwm0_pwm_h0: pwm0_pwm_h0 {
+                       pinmux = <PIN_PA30__PWMH0>;
+                       bias-disable;
+               };
+               pinctrl_pwm0_pwm_h1: pwm0_pwmh1 {
+                       pinmux = <PIN_PB0__PWMH1>;
+                       bias-disable;
+               };
+               pinctrl_pwm0_pwm_h2: pwm0_pwm_h2 {
+                       pinmux = <PIN_PB5__PWMH2>;
+                       bias-disable;
+               };
+               pinctrl_pwm0_pwm_h3: pwm0_pwm_h3 {
+                       pinmux = <PIN_PB7__PWMH3>;
+                       bias-disable;
+               };
+       };
+
+       pinctrl_adc {
+               pinctrl_adc2: adc2 {
+                       pinmux = <PIN_PD21__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_adc3: adc3 {
+                       pinmux = <PIN_PD22__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_adc4: adc4 {
+                       pinmux = <PIN_PD23__GPIO>;
+                       bias-disable;
+               };
+               pinctrl_adc5: adc5 {
+                       pinmux = <PIN_PD24__GPIO>;
+                       bias-disable;
+               };
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart_0>;
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+/* debug uart */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart_1>;
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart_2>;
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart_3>;
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart_4>;
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "disabled";
+};
+
+&flx0 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+       status = "disabled";
+
+       uart5: serial@200  {
+               compatible = "atmel,at91sam9260-usart";
+               reg = <0x200 0x400>;
+               interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
+               dmas = <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+                       | AT91_XDMAC_DT_PERID(11))>,
+                      <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+                       | AT91_XDMAC_DT_PERID(12))>;
+               dma-names = "tx", "rx";
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
+               clock-names = "usart";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_flx0_default>;
+               atmel,fifo-size = <32>;
+               atmel,use-dma-rx;
+               atmel,use-dma-tx;
+               status = "disabled";
+       };
+};
+
+&flx3 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+       status = "disabled";
+
+       uart6: serial@200 {
+               compatible = "atmel,at91sam9260-usart";
+               reg = <0x200 0x400>;
+               interrupts = <22 IRQ_TYPE_LEVEL_HIGH 7>;
+               dmas = <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+                       | AT91_XDMAC_DT_PERID(17))>,
+                      <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+                       | AT91_XDMAC_DT_PERID(18))>;
+               dma-names = "tx", "rx";
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 22>;
+               clock-names = "usart";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_flx3_default>;
+               atmel,fifo-size = <32>;
+               atmel,use-dma-rx;
+               atmel,use-dma-tx;
+               status = "disabled";
+       };
+};
+
+&flx4 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+       status = "disabled";
+
+       i2c2: i2c@600 {
+               compatible = "atmel,sama5d2-i2c";
+               reg = <0x600 0x200>;
+               interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>;
+               dmas = <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+                       | AT91_XDMAC_DT_PERID(19))>,
+                      <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+                       | AT91_XDMAC_DT_PERID(20))>;
+               dma-names = "tx", "rx";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 23>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_flx4_default>;
+               atmel,fifo-size = <16>;
+               status = "disabled";
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&shutdown_controller {
+       atmel,shdwc-debouncer = <976>;
+       atmel,wakeup-rtc-timer;
+
+       input@0 {
+               reg = <0>;
+               atmel,wakeup-type = "low";
+       };
+};
+
+&watchdog {
+       status = "okay";
+};
+
+&adc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc2
+                    &pinctrl_adc3
+                    &pinctrl_adc4
+                    &pinctrl_adc5>;
+
+       vddana-supply = <&vdd_adc_vddana>;
+       vref-supply = <&vdd_adc_vref>;
+       status = "disabled";
+};
+
+&securam {
+       export;
+
+       /* export overkiz u-boot mode/version and factory */
+       uboot@1400 {
+               reg = <0x1400 0x20>;
+               export;
+       };
+};
index 89f0c99..fca5716 100644 (file)
@@ -53,6 +53,7 @@
 
                sdmmc0: sdio-host@a0000000 {
                        bus-width = <8>;
+                       mmc-ddr-3_3v;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_sdmmc0_default>;
                        status = "okay";
index 808e399..9d0a7fb 100644 (file)
                                        pinctrl-names = "default";
                                        pinctrl-0 = <&pinctrl_flx4_default>;
                                        atmel,fifo-size = <16>;
+                                       i2c-analog-filter;
+                                       i2c-digital-filter;
+                                       i2c-digital-filter-width-ns = <35>;
                                        status = "okay";
                                };
                        };
                                dmas = <0>, <0>;
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_i2c1_default>;
+                               i2c-analog-filter;
+                               i2c-digital-filter;
+                               i2c-digital-filter-width-ns = <35>;
                                status = "okay";
 
                                at24@54 {
index fdfc37d..924d949 100644 (file)
@@ -49,6 +49,7 @@
                        };
 
                        i2c0: i2c@f8014000 {
+                               i2c-digital-filter;
                                status = "okay";
                        };
 
index e0c0291..e051504 100644 (file)
                                label = "rearview key";
                                linux,code = <KEY_CAMERA>;
                                gpios = <&gpio_1 3 GPIO_ACTIVE_LOW>;
-                               debounce_interval = <100>;
+                               debounce-interval = <100>;
                        };
                };
 
index 2dac3ef..1bc45cf 100644 (file)
                mdio: mdio@18002000 {
                        compatible = "brcm,iproc-mdio";
                        reg = <0x18002000 0x8>;
-                       #size-cells = <1>;
-                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       #address-cells = <1>;
                        status = "disabled";
 
                        gphy0: ethernet-phy@0 {
index e4d4973..6142c67 100644 (file)
                        clock-frequency = <100000>;
                };
 
-               watchdog@39000 {
+               watchdog: watchdog@39000 {
                        compatible = "arm,sp805", "arm,primecell";
                        reg = <0x39000 0x1000>;
                        interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
new file mode 100644 (file)
index 0000000..1b5a835
--- /dev/null
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2711.dtsi"
+#include "bcm2835-rpi.dtsi"
+#include "bcm283x-rpi-usb-peripheral.dtsi"
+
+/ {
+       compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
+       model = "Raspberry Pi 4 Model B";
+
+       chosen {
+               /* 8250 auxiliary UART instead of pl011 */
+               stdout-path = "serial1:115200n8";
+       };
+
+       /* Will be filled by the bootloader */
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0 0>;
+       };
+
+       aliases {
+               ethernet0 = &genet;
+       };
+
+       leds {
+               act {
+                       gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
+               };
+
+               pwr {
+                       label = "PWR";
+                       gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       wifi_pwrseq: wifi-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+       };
+
+       sd_io_1v8_reg: sd_io_1v8_reg {
+               compatible = "regulator-gpio";
+               regulator-name = "vdd-sd-io";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+               regulator-settling-time-us = <5000>;
+               gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x1
+                         3300000 0x0>;
+               status = "okay";
+       };
+};
+
+&firmware {
+       expgpio: gpio {
+               compatible = "raspberrypi,firmware-gpio";
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-line-names = "BT_ON",
+                                 "WL_ON",
+                                 "PWR_LED_OFF",
+                                 "GLOBAL_RESET",
+                                 "VDD_SD_IO_SEL",
+                                 "CAM_GPIO",
+                                 "",
+                                 "";
+               status = "okay";
+       };
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>;
+       status = "okay";
+};
+
+/* SDHCI is used to control the SDIO for wireless */
+&sdhci {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_gpio34>;
+       bus-width = <4>;
+       non-removable;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
+
+/* EMMC2 is used to drive the SD card */
+&emmc2 {
+       vqmmc-supply = <&sd_io_1v8_reg>;
+       broken-cd;
+       status = "okay";
+};
+
+&genet {
+       phy-handle = <&phy1>;
+       phy-mode = "rgmii-rxid";
+       status = "okay";
+};
+
+&genet_mdio {
+       phy1: ethernet-phy@1 {
+               /* No PHY interrupt */
+               reg = <0x1>;
+       };
+};
+
+/* uart0 communicates with the BT module */
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               max-speed = <2000000>;
+               shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+/* uart1 is mapped to the pin header */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_gpio14>;
+       status = "okay";
+};
+
+&vchiq {
+       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
new file mode 100644 (file)
index 0000000..e2f6ffb
--- /dev/null
@@ -0,0 +1,890 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "bcm283x.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/bcm2835-pm.h>
+
+/ {
+       compatible = "brcm,bcm2711";
+
+       #address-cells = <2>;
+       #size-cells = <1>;
+
+       interrupt-parent = <&gicv2>;
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges;
+
+               /*
+                * arm64 reserves the CMA by default somewhere in ZONE_DMA32,
+                * that's not good enough for the BCM2711 as some devices can
+                * only address the lower 1G of memory (ZONE_DMA).
+                */
+               linux,cma {
+                       compatible = "shared-dma-pool";
+                       size = <0x2000000>; /* 32MB */
+                       alloc-ranges = <0x0 0x00000000 0x40000000>;
+                       reusable;
+                       linux,cma-default;
+               };
+       };
+
+
+       soc {
+               /*
+                * Defined ranges:
+                *   Common BCM283x peripherals
+                *   BCM2711-specific peripherals
+                *   ARM-local peripherals
+                */
+               ranges = <0x7e000000  0x0 0xfe000000  0x01800000>,
+                        <0x7c000000  0x0 0xfc000000  0x02000000>,
+                        <0x40000000  0x0 0xff800000  0x00800000>;
+               /* Emulate a contiguous 30-bit address range for DMA */
+               dma-ranges = <0xc0000000  0x0 0x00000000  0x40000000>;
+
+               /*
+                * This node is the provider for the enable-method for
+                * bringing up secondary cores.
+                */
+               local_intc: local_intc@40000000 {
+                       compatible = "brcm,bcm2836-l1-intc";
+                       reg = <0x40000000 0x100>;
+               };
+
+               gicv2: interrupt-controller@40041000 {
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       compatible = "arm,gic-400";
+                       reg =   <0x40041000 0x1000>,
+                               <0x40042000 0x2000>,
+                               <0x40044000 0x2000>,
+                               <0x40046000 0x2000>;
+                       interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+                                                IRQ_TYPE_LEVEL_HIGH)>;
+               };
+
+               dma: dma@7e007000 {
+                       compatible = "brcm,bcm2835-dma";
+                       reg = <0x7e007000 0xb00>;
+                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+                                    /* DMA lite 7 - 10 */
+                                    <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "dma0",
+                                         "dma1",
+                                         "dma2",
+                                         "dma3",
+                                         "dma4",
+                                         "dma5",
+                                         "dma6",
+                                         "dma7",
+                                         "dma8",
+                                         "dma9",
+                                         "dma10";
+                       #dma-cells = <1>;
+                       brcm,dma-channel-mask = <0x07f5>;
+               };
+
+               pm: watchdog@7e100000 {
+                       compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt";
+                       #power-domain-cells = <1>;
+                       #reset-cells = <1>;
+                       reg = <0x7e100000 0x114>,
+                             <0x7e00a000 0x24>,
+                             <0x7ec11000 0x20>;
+                       clocks = <&clocks BCM2835_CLOCK_V3D>,
+                                <&clocks BCM2835_CLOCK_PERI_IMAGE>,
+                                <&clocks BCM2835_CLOCK_H264>,
+                                <&clocks BCM2835_CLOCK_ISP>;
+                       clock-names = "v3d", "peri_image", "h264", "isp";
+                       system-power-controller;
+               };
+
+               rng@7e104000 {
+                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+
+                       /* RNG is incompatible with brcm,bcm2835-rng */
+                       status = "disabled";
+               };
+
+               uart2: serial@7e201400 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x7e201400 0x200>;
+                       interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_UART>,
+                                <&clocks BCM2835_CLOCK_VPU>;
+                       clock-names = "uartclk", "apb_pclk";
+                       arm,primecell-periphid = <0x00241011>;
+                       status = "disabled";
+               };
+
+               uart3: serial@7e201600 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x7e201600 0x200>;
+                       interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_UART>,
+                                <&clocks BCM2835_CLOCK_VPU>;
+                       clock-names = "uartclk", "apb_pclk";
+                       arm,primecell-periphid = <0x00241011>;
+                       status = "disabled";
+               };
+
+               uart4: serial@7e201800 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x7e201800 0x200>;
+                       interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_UART>,
+                                <&clocks BCM2835_CLOCK_VPU>;
+                       clock-names = "uartclk", "apb_pclk";
+                       arm,primecell-periphid = <0x00241011>;
+                       status = "disabled";
+               };
+
+               uart5: serial@7e201a00 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x7e201a00 0x200>;
+                       interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_UART>,
+                                <&clocks BCM2835_CLOCK_VPU>;
+                       clock-names = "uartclk", "apb_pclk";
+                       arm,primecell-periphid = <0x00241011>;
+                       status = "disabled";
+               };
+
+               spi3: spi@7e204600 {
+                       compatible = "brcm,bcm2835-spi";
+                       reg = <0x7e204600 0x0200>;
+                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi4: spi@7e204800 {
+                       compatible = "brcm,bcm2835-spi";
+                       reg = <0x7e204800 0x0200>;
+                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi5: spi@7e204a00 {
+                       compatible = "brcm,bcm2835-spi";
+                       reg = <0x7e204a00 0x0200>;
+                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi6: spi@7e204c00 {
+                       compatible = "brcm,bcm2835-spi";
+                       reg = <0x7e204c00 0x0200>;
+                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@7e205600 {
+                       compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+                       reg = <0x7e205600 0x200>;
+                       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@7e205800 {
+                       compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+                       reg = <0x7e205800 0x200>;
+                       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@7e205a00 {
+                       compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+                       reg = <0x7e205a00 0x200>;
+                       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c6: i2c@7e205c00 {
+                       compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+                       reg = <0x7e205c00 0x200>;
+                       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               pwm1: pwm@7e20c800 {
+                       compatible = "brcm,bcm2835-pwm";
+                       reg = <0x7e20c800 0x28>;
+                       clocks = <&clocks BCM2835_CLOCK_PWM>;
+                       assigned-clocks = <&clocks BCM2835_CLOCK_PWM>;
+                       assigned-clock-rates = <10000000>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
+               emmc2: emmc2@7e340000 {
+                       compatible = "brcm,bcm2711-emmc2";
+                       reg = <0x7e340000 0x100>;
+                       interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clocks BCM2711_CLOCK_EMMC2>;
+                       status = "disabled";
+               };
+
+               hvs@7e400000 {
+                       interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+               };
+       };
+
+       arm-pmu {
+               compatible = "arm,cortex-a72-pmu", "arm,armv8-pmuv3";
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                       <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                       <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                       <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>;
+               /* This only applies to the ARMv7 stub */
+               arm,cpu-registers-not-fw-configured;
+       };
+
+       cpus: cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72";
+                       reg = <0>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x000000d8>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72";
+                       reg = <1>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x000000e0>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72";
+                       reg = <2>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x000000e8>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72";
+                       reg = <3>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x000000f0>;
+               };
+       };
+
+       scb {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+
+               ranges = <0x0 0x7c000000  0x0 0xfc000000  0x03800000>;
+
+               genet: ethernet@7d580000 {
+                       compatible = "brcm,bcm2711-genet-v5";
+                       reg = <0x0 0x7d580000 0x10000>;
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+
+                       genet_mdio: mdio@e14 {
+                               compatible = "brcm,genet-mdio-v5";
+                               reg = <0xe14 0x8>;
+                               reg-names = "mdio";
+                               #address-cells = <0x0>;
+                               #size-cells = <0x1>;
+                       };
+               };
+       };
+};
+
+&clk_osc {
+       clock-frequency = <54000000>;
+};
+
+&clocks {
+       compatible = "brcm,bcm2711-cprman";
+};
+
+&cpu_thermal {
+       coefficients = <(-487) 410040>;
+};
+
+&dsi0 {
+       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&dsi1 {
+       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&gpio {
+       compatible = "brcm,bcm2711-gpio";
+       interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+
+       gpclk0_gpio49: gpclk0_gpio49 {
+               pin-gpclk {
+                       pins = "gpio49";
+                       function = "alt1";
+                       bias-disable;
+               };
+       };
+       gpclk1_gpio50: gpclk1_gpio50 {
+               pin-gpclk {
+                       pins = "gpio50";
+                       function = "alt1";
+                       bias-disable;
+               };
+       };
+       gpclk2_gpio51: gpclk2_gpio51 {
+               pin-gpclk {
+                       pins = "gpio51";
+                       function = "alt1";
+                       bias-disable;
+               };
+       };
+
+       i2c0_gpio46: i2c0_gpio46 {
+               pin-sda {
+                       function = "alt0";
+                       pins = "gpio46";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt0";
+                       pins = "gpio47";
+                       bias-disable;
+               };
+       };
+       i2c1_gpio46: i2c1_gpio46 {
+               pin-sda {
+                       function = "alt1";
+                       pins = "gpio46";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt1";
+                       pins = "gpio47";
+                       bias-disable;
+               };
+       };
+       i2c3_gpio2: i2c3_gpio2 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio2";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio3";
+                       bias-disable;
+               };
+       };
+       i2c3_gpio4: i2c3_gpio4 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio4";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio5";
+                       bias-disable;
+               };
+       };
+       i2c4_gpio6: i2c4_gpio6 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio6";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio7";
+                       bias-disable;
+               };
+       };
+       i2c4_gpio8: i2c4_gpio8 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio8";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio9";
+                       bias-disable;
+               };
+       };
+       i2c5_gpio10: i2c5_gpio10 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio10";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio11";
+                       bias-disable;
+               };
+       };
+       i2c5_gpio12: i2c5_gpio12 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio12";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio13";
+                       bias-disable;
+               };
+       };
+       i2c6_gpio0: i2c6_gpio0 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio0";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio1";
+                       bias-disable;
+               };
+       };
+       i2c6_gpio22: i2c6_gpio22 {
+               pin-sda {
+                       function = "alt5";
+                       pins = "gpio22";
+                       bias-pull-up;
+               };
+               pin-scl {
+                       function = "alt5";
+                       pins = "gpio23";
+                       bias-disable;
+               };
+       };
+       i2c_slave_gpio8: i2c_slave_gpio8 {
+               pins-i2c-slave {
+                       pins = "gpio8",
+                              "gpio9",
+                              "gpio10",
+                              "gpio11";
+                       function = "alt3";
+               };
+       };
+
+       jtag_gpio48: jtag_gpio48 {
+               pins-jtag {
+                       pins = "gpio48",
+                              "gpio49",
+                              "gpio50",
+                              "gpio51",
+                              "gpio52",
+                              "gpio53";
+                       function = "alt4";
+               };
+       };
+
+       mii_gpio28: mii_gpio28 {
+               pins-mii {
+                       pins = "gpio28",
+                              "gpio29",
+                              "gpio30",
+                              "gpio31";
+                       function = "alt4";
+               };
+       };
+       mii_gpio36: mii_gpio36 {
+               pins-mii {
+                       pins = "gpio36",
+                              "gpio37",
+                              "gpio38",
+                              "gpio39";
+                       function = "alt5";
+               };
+       };
+
+       pcm_gpio50: pcm_gpio50 {
+               pins-pcm {
+                       pins = "gpio50",
+                              "gpio51",
+                              "gpio52",
+                              "gpio53";
+                       function = "alt2";
+               };
+       };
+
+       pwm0_0_gpio12: pwm0_0_gpio12 {
+               pin-pwm {
+                       pins = "gpio12";
+                       function = "alt0";
+                       bias-disable;
+               };
+       };
+       pwm0_0_gpio18: pwm0_0_gpio18 {
+               pin-pwm {
+                       pins = "gpio18";
+                       function = "alt5";
+                       bias-disable;
+               };
+       };
+       pwm1_0_gpio40: pwm1_0_gpio40 {
+               pin-pwm {
+                       pins = "gpio40";
+                       function = "alt0";
+                       bias-disable;
+               };
+       };
+       pwm0_1_gpio13: pwm0_1_gpio13 {
+               pin-pwm {
+                       pins = "gpio13";
+                       function = "alt0";
+                       bias-disable;
+               };
+       };
+       pwm0_1_gpio19: pwm0_1_gpio19 {
+               pin-pwm {
+                       pins = "gpio19";
+                       function = "alt5";
+                       bias-disable;
+               };
+       };
+       pwm1_1_gpio41: pwm1_1_gpio41 {
+               pin-pwm {
+                       pins = "gpio41";
+                       function = "alt0";
+                       bias-disable;
+               };
+       };
+       pwm0_1_gpio45: pwm0_1_gpio45 {
+               pin-pwm {
+                       pins = "gpio45";
+                       function = "alt0";
+                       bias-disable;
+               };
+       };
+       pwm0_0_gpio52: pwm0_0_gpio52 {
+               pin-pwm {
+                       pins = "gpio52";
+                       function = "alt1";
+                       bias-disable;
+               };
+       };
+       pwm0_1_gpio53: pwm0_1_gpio53 {
+               pin-pwm {
+                       pins = "gpio53";
+                       function = "alt1";
+                       bias-disable;
+               };
+       };
+
+       rgmii_gpio35: rgmii_gpio35 {
+               pin-start-stop {
+                       pins = "gpio35";
+                       function = "alt4";
+               };
+               pin-rx-ok {
+                       pins = "gpio36";
+                       function = "alt4";
+               };
+       };
+       rgmii_irq_gpio34: rgmii_irq_gpio34 {
+               pin-irq {
+                       pins = "gpio34";
+                       function = "alt5";
+               };
+       };
+       rgmii_irq_gpio39: rgmii_irq_gpio39 {
+               pin-irq {
+                       pins = "gpio39";
+                       function = "alt4";
+               };
+       };
+       rgmii_mdio_gpio28: rgmii_mdio_gpio28 {
+               pins-mdio {
+                       pins = "gpio28",
+                              "gpio29";
+                       function = "alt5";
+               };
+       };
+       rgmii_mdio_gpio37: rgmii_mdio_gpio37 {
+               pins-mdio {
+                       pins = "gpio37",
+                              "gpio38";
+                       function = "alt4";
+               };
+       };
+
+       spi0_gpio46: spi0_gpio46 {
+               pins-spi {
+                       pins = "gpio46",
+                              "gpio47",
+                              "gpio48",
+                              "gpio49";
+                       function = "alt2";
+               };
+       };
+       spi2_gpio46: spi2_gpio46 {
+               pins-spi {
+                       pins = "gpio46",
+                              "gpio47",
+                              "gpio48",
+                              "gpio49",
+                              "gpio50";
+                       function = "alt5";
+               };
+       };
+       spi3_gpio0: spi3_gpio0 {
+               pins-spi {
+                       pins = "gpio0",
+                              "gpio1",
+                              "gpio2",
+                              "gpio3";
+                       function = "alt3";
+               };
+       };
+       spi4_gpio4: spi4_gpio4 {
+               pins-spi {
+                       pins = "gpio4",
+                              "gpio5",
+                              "gpio6",
+                              "gpio7";
+                       function = "alt3";
+               };
+       };
+       spi5_gpio12: spi5_gpio12 {
+               pins-spi {
+                       pins = "gpio12",
+                              "gpio13",
+                              "gpio14",
+                              "gpio15";
+                       function = "alt3";
+               };
+       };
+       spi6_gpio18: spi6_gpio18 {
+               pins-spi {
+                       pins = "gpio18",
+                              "gpio19",
+                              "gpio20",
+                              "gpio21";
+                       function = "alt3";
+               };
+       };
+
+       uart2_gpio0: uart2_gpio0 {
+               pin-tx {
+                       pins = "gpio0";
+                       function = "alt4";
+                       bias-disable;
+               };
+               pin-rx {
+                       pins = "gpio1";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+       };
+       uart2_ctsrts_gpio2: uart2_ctsrts_gpio2 {
+               pin-cts {
+                       pins = "gpio2";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+               pin-rts {
+                       pins = "gpio3";
+                       function = "alt4";
+                       bias-disable;
+               };
+       };
+       uart3_gpio4: uart3_gpio4 {
+               pin-tx {
+                       pins = "gpio4";
+                       function = "alt4";
+                       bias-disable;
+               };
+               pin-rx {
+                       pins = "gpio5";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+       };
+       uart3_ctsrts_gpio6: uart3_ctsrts_gpio6 {
+               pin-cts {
+                       pins = "gpio6";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+               pin-rts {
+                       pins = "gpio7";
+                       function = "alt4";
+                       bias-disable;
+               };
+       };
+       uart4_gpio8: uart4_gpio8 {
+               pin-tx {
+                       pins = "gpio8";
+                       function = "alt4";
+                       bias-disable;
+               };
+               pin-rx {
+                       pins = "gpio9";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+       };
+       uart4_ctsrts_gpio10: uart4_ctsrts_gpio10 {
+               pin-cts {
+                       pins = "gpio10";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+               pin-rts {
+                       pins = "gpio11";
+                       function = "alt4";
+                       bias-disable;
+               };
+       };
+       uart5_gpio12: uart5_gpio12 {
+               pin-tx {
+                       pins = "gpio12";
+                       function = "alt4";
+                       bias-disable;
+               };
+               pin-rx {
+                       pins = "gpio13";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+       };
+       uart5_ctsrts_gpio14: uart5_ctsrts_gpio14 {
+               pin-cts {
+                       pins = "gpio14";
+                       function = "alt4";
+                       bias-pull-up;
+               };
+               pin-rts {
+                       pins = "gpio15";
+                       function = "alt4";
+                       bias-disable;
+               };
+       };
+};
+
+&i2c0 {
+       compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&i2c1 {
+       compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mailbox {
+       interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&sdhci {
+       interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&sdhost {
+       interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&spi {
+       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&spi1 {
+       interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&spi2 {
+       interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&system_timer {
+       interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&txp {
+       interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&uart0 {
+       interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&uart1 {
+       interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&usb {
+       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&vec {
+       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/arch/arm/boot/dts/bcm2835-common.dtsi b/arch/arm/boot/dts/bcm2835-common.dtsi
new file mode 100644 (file)
index 0000000..fe1ab40
--- /dev/null
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* This include file covers the common peripherals and configuration between
+ * bcm2835, bcm2836 and bcm2837 implementations.
+ */
+
+/ {
+       interrupt-parent = <&intc>;
+
+       soc {
+               dma: dma@7e007000 {
+                       compatible = "brcm,bcm2835-dma";
+                       reg = <0x7e007000 0xf00>;
+                       interrupts = <1 16>,
+                                    <1 17>,
+                                    <1 18>,
+                                    <1 19>,
+                                    <1 20>,
+                                    <1 21>,
+                                    <1 22>,
+                                    <1 23>,
+                                    <1 24>,
+                                    <1 25>,
+                                    <1 26>,
+                                    /* dma channel 11-14 share one irq */
+                                    <1 27>,
+                                    <1 27>,
+                                    <1 27>,
+                                    <1 27>,
+                                    /* unused shared irq for all channels */
+                                    <1 28>;
+                       interrupt-names = "dma0",
+                                         "dma1",
+                                         "dma2",
+                                         "dma3",
+                                         "dma4",
+                                         "dma5",
+                                         "dma6",
+                                         "dma7",
+                                         "dma8",
+                                         "dma9",
+                                         "dma10",
+                                         "dma11",
+                                         "dma12",
+                                         "dma13",
+                                         "dma14",
+                                         "dma-shared-all";
+                       #dma-cells = <1>;
+                       brcm,dma-channel-mask = <0x7f35>;
+               };
+
+               intc: interrupt-controller@7e00b200 {
+                       compatible = "brcm,bcm2835-armctrl-ic";
+                       reg = <0x7e00b200 0x200>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               pm: watchdog@7e100000 {
+                       compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt";
+                       #power-domain-cells = <1>;
+                       #reset-cells = <1>;
+                       reg = <0x7e100000 0x114>,
+                             <0x7e00a000 0x24>;
+                       clocks = <&clocks BCM2835_CLOCK_V3D>,
+                                <&clocks BCM2835_CLOCK_PERI_IMAGE>,
+                                <&clocks BCM2835_CLOCK_H264>,
+                                <&clocks BCM2835_CLOCK_ISP>;
+                       clock-names = "v3d", "peri_image", "h264", "isp";
+                       system-power-controller;
+               };
+
+               pixelvalve@7e206000 {
+                       compatible = "brcm,bcm2835-pixelvalve0";
+                       reg = <0x7e206000 0x100>;
+                       interrupts = <2 13>; /* pwa0 */
+               };
+
+               pixelvalve@7e207000 {
+                       compatible = "brcm,bcm2835-pixelvalve1";
+                       reg = <0x7e207000 0x100>;
+                       interrupts = <2 14>; /* pwa1 */
+               };
+
+               thermal: thermal@7e212000 {
+                       compatible = "brcm,bcm2835-thermal";
+                       reg = <0x7e212000 0x8>;
+                       clocks = <&clocks BCM2835_CLOCK_TSENS>;
+                       #thermal-sensor-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 = "okay";
+               };
+
+               pixelvalve@7e807000 {
+                       compatible = "brcm,bcm2835-pixelvalve2";
+                       reg = <0x7e807000 0x100>;
+                       interrupts = <2 10>; /* pixelvalve */
+               };
+
+               hdmi: hdmi@7e902000 {
+                       compatible = "brcm,bcm2835-hdmi";
+                       reg = <0x7e902000 0x600>,
+                             <0x7e808000 0x100>;
+                       interrupts = <2 8>, <2 9>;
+                       ddc = <&i2c2>;
+                       clocks = <&clocks BCM2835_PLLH_PIX>,
+                                <&clocks BCM2835_CLOCK_HSM>;
+                       clock-names = "pixel", "hdmi";
+                       dmas = <&dma 17>;
+                       dma-names = "audio-rx";
+                       status = "disabled";
+               };
+
+               v3d: v3d@7ec00000 {
+                       compatible = "brcm,bcm2835-v3d";
+                       reg = <0x7ec00000 0x1000>;
+                       interrupts = <1 10>;
+                       power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
+               };
+
+               vc4: gpu {
+                       compatible = "brcm,bcm2835-vc4";
+               };
+       };
+};
+
+&cpu_thermal {
+       thermal-sensors = <&thermal>;
+};
+
+&gpio {
+       i2c_slave_gpio18: i2c_slave_gpio18 {
+               brcm,pins = <18 19 20 21>;
+               brcm,function = <BCM2835_FSEL_ALT3>;
+       };
+
+       jtag_gpio4: jtag_gpio4 {
+               brcm,pins = <4 5 6 12 13>;
+               brcm,function = <BCM2835_FSEL_ALT5>;
+       };
+
+       pwm0_gpio12: pwm0_gpio12 {
+               brcm,pins = <12>;
+               brcm,function = <BCM2835_FSEL_ALT0>;
+       };
+       pwm0_gpio18: pwm0_gpio18 {
+               brcm,pins = <18>;
+               brcm,function = <BCM2835_FSEL_ALT5>;
+       };
+       pwm0_gpio40: pwm0_gpio40 {
+               brcm,pins = <40>;
+               brcm,function = <BCM2835_FSEL_ALT0>;
+       };
+       pwm1_gpio13: pwm1_gpio13 {
+               brcm,pins = <13>;
+               brcm,function = <BCM2835_FSEL_ALT0>;
+       };
+       pwm1_gpio19: pwm1_gpio19 {
+               brcm,pins = <19>;
+               brcm,function = <BCM2835_FSEL_ALT5>;
+       };
+       pwm1_gpio41: pwm1_gpio41 {
+               brcm,pins = <41>;
+               brcm,function = <BCM2835_FSEL_ALT0>;
+       };
+       pwm1_gpio45: pwm1_gpio45 {
+               brcm,pins = <45>;
+               brcm,function = <BCM2835_FSEL_ALT0>;
+       };
+};
+
+&i2s {
+       dmas = <&dma 2>, <&dma 3>;
+       dma-names = "tx", "rx";
+};
+
+&sdhost {
+       dmas = <&dma 13>;
+       dma-names = "rx-tx";
+};
+
+&spi {
+       dmas = <&dma 6>, <&dma 7>;
+       dma-names = "tx", "rx";
+};
index 6c6a7f6..394c8a7 100644 (file)
        clock-frequency = <100000>;
 };
 
-&i2c2 {
-       status = "okay";
-};
-
 &usb {
        power-domains = <&power RPI_POWER_DOMAIN_USB>;
 };
index a5c3824..53bf457 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcm283x.dtsi"
+#include "bcm2835-common.dtsi"
 
 / {
        compatible = "brcm,bcm2835";
index c933e84..82d6c46 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcm283x.dtsi"
+#include "bcm2835-common.dtsi"
 
 / {
        compatible = "brcm,bcm2836";
index beb6c50..9e95fee 100644 (file)
@@ -1,4 +1,5 @@
 #include "bcm283x.dtsi"
+#include "bcm2835-common.dtsi"
 
 / {
        compatible = "brcm,bcm2837";
diff --git a/arch/arm/boot/dts/bcm283x-rpi-usb-peripheral.dtsi b/arch/arm/boot/dts/bcm283x-rpi-usb-peripheral.dtsi
new file mode 100644 (file)
index 0000000..0ff0e9e
--- /dev/null
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
+&usb {
+       dr_mode = "peripheral";
+       g-rx-fifo-size = <256>;
+       g-np-tx-fifo-size = <32>;
+       g-tx-fifo-size = <256 256 512 512 512 768 768>;
+};
index 2d191fc..8394916 100644 (file)
@@ -18,7 +18,6 @@
 / {
        compatible = "brcm,bcm2835";
        model = "BCM2835";
-       interrupt-parent = <&intc>;
        #address-cells = <1>;
        #size-cells = <1>;
 
                        polling-delay-passive = <0>;
                        polling-delay = <1000>;
 
-                       thermal-sensors = <&thermal>;
-
                        trips {
                                cpu-crit {
-                                       temperature     = <80000>;
+                                       temperature     = <90000>;
                                        hysteresis      = <0>;
                                        type            = "critical";
                                };
@@ -56,7 +53,7 @@
                #address-cells = <1>;
                #size-cells = <1>;
 
-               timer@7e003000 {
+               system_timer: timer@7e003000 {
                        compatible = "brcm,bcm2835-system-timer";
                        reg = <0x7e003000 0x1000>;
                        interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
                        clock-frequency = <1000000>;
                };
 
-               txp@7e004000 {
+               txp: txp@7e004000 {
                        compatible = "brcm,bcm2835-txp";
                        reg = <0x7e004000 0x20>;
                        interrupts = <1 11>;
                };
 
-               dma: dma@7e007000 {
-                       compatible = "brcm,bcm2835-dma";
-                       reg = <0x7e007000 0xf00>;
-                       interrupts = <1 16>,
-                                    <1 17>,
-                                    <1 18>,
-                                    <1 19>,
-                                    <1 20>,
-                                    <1 21>,
-                                    <1 22>,
-                                    <1 23>,
-                                    <1 24>,
-                                    <1 25>,
-                                    <1 26>,
-                                    /* dma channel 11-14 share one irq */
-                                    <1 27>,
-                                    <1 27>,
-                                    <1 27>,
-                                    <1 27>,
-                                    /* unused shared irq for all channels */
-                                    <1 28>;
-                       interrupt-names = "dma0",
-                                         "dma1",
-                                         "dma2",
-                                         "dma3",
-                                         "dma4",
-                                         "dma5",
-                                         "dma6",
-                                         "dma7",
-                                         "dma8",
-                                         "dma9",
-                                         "dma10",
-                                         "dma11",
-                                         "dma12",
-                                         "dma13",
-                                         "dma14",
-                                         "dma-shared-all";
-                       #dma-cells = <1>;
-                       brcm,dma-channel-mask = <0x7f35>;
-               };
-
-               intc: interrupt-controller@7e00b200 {
-                       compatible = "brcm,bcm2835-armctrl-ic";
-                       reg = <0x7e00b200 0x200>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               pm: watchdog@7e100000 {
-                       compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt";
-                       #power-domain-cells = <1>;
-                       #reset-cells = <1>;
-                       reg = <0x7e100000 0x114>,
-                             <0x7e00a000 0x24>;
-                       clocks = <&clocks BCM2835_CLOCK_V3D>,
-                                <&clocks BCM2835_CLOCK_PERI_IMAGE>,
-                                <&clocks BCM2835_CLOCK_H264>,
-                                <&clocks BCM2835_CLOCK_ISP>;
-                       clock-names = "v3d", "peri_image", "h264", "isp";
-                       system-power-controller;
-               };
-
                clocks: cprman@7e101000 {
                        compatible = "brcm,bcm2835-cprman";
                        #clock-cells = <1>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
 
-                       /* Defines pin muxing groups according to
-                        * BCM2835-ARM-Peripherals.pdf page 102.
+                       /* Defines common pin muxing groups
                         *
                         * While each pin can have its mux selected
                         * for various functions individually, some
                                brcm,pins = <44 45>;
                                brcm,function = <BCM2835_FSEL_ALT2>;
                        };
-                       i2c_slave_gpio18: i2c_slave_gpio18 {
-                               brcm,pins = <18 19 20 21>;
-                               brcm,function = <BCM2835_FSEL_ALT3>;
-                       };
 
-                       jtag_gpio4: jtag_gpio4 {
-                               brcm,pins = <4 5 6 12 13>;
-                               brcm,function = <BCM2835_FSEL_ALT5>;
-                       };
                        jtag_gpio22: jtag_gpio22 {
                                brcm,pins = <22 23 24 25 26 27>;
                                brcm,function = <BCM2835_FSEL_ALT4>;
                                brcm,function = <BCM2835_FSEL_ALT2>;
                        };
 
-                       pwm0_gpio12: pwm0_gpio12 {
-                               brcm,pins = <12>;
-                               brcm,function = <BCM2835_FSEL_ALT0>;
-                       };
-                       pwm0_gpio18: pwm0_gpio18 {
-                               brcm,pins = <18>;
-                               brcm,function = <BCM2835_FSEL_ALT5>;
-                       };
-                       pwm0_gpio40: pwm0_gpio40 {
-                               brcm,pins = <40>;
-                               brcm,function = <BCM2835_FSEL_ALT0>;
-                       };
-                       pwm1_gpio13: pwm1_gpio13 {
-                               brcm,pins = <13>;
-                               brcm,function = <BCM2835_FSEL_ALT0>;
-                       };
-                       pwm1_gpio19: pwm1_gpio19 {
-                               brcm,pins = <19>;
-                               brcm,function = <BCM2835_FSEL_ALT5>;
-                       };
-                       pwm1_gpio41: pwm1_gpio41 {
-                               brcm,pins = <41>;
-                               brcm,function = <BCM2835_FSEL_ALT0>;
-                       };
-                       pwm1_gpio45: pwm1_gpio45 {
-                               brcm,pins = <45>;
-                               brcm,function = <BCM2835_FSEL_ALT0>;
-                       };
-
                        sdhost_gpio48: sdhost_gpio48 {
                                brcm,pins = <48 49 50 51 52 53>;
                                brcm,function = <BCM2835_FSEL_ALT0>;
                };
 
                uart0: serial@7e201000 {
-                       compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+                       compatible = "arm,pl011", "arm,primecell";
                        reg = <0x7e201000 0x200>;
                        interrupts = <2 25>;
                        clocks = <&clocks BCM2835_CLOCK_UART>,
                        reg = <0x7e202000 0x100>;
                        interrupts = <2 24>;
                        clocks = <&clocks BCM2835_CLOCK_VPU>;
-                       dmas = <&dma 13>;
-                       dma-names = "rx-tx";
                        status = "disabled";
                };
 
                        compatible = "brcm,bcm2835-i2s";
                        reg = <0x7e203000 0x24>;
                        clocks = <&clocks BCM2835_CLOCK_PCM>;
-
-                       dmas = <&dma 2>,
-                              <&dma 3>;
-                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        reg = <0x7e204000 0x200>;
                        interrupts = <2 22>;
                        clocks = <&clocks BCM2835_CLOCK_VPU>;
-                       dmas = <&dma 6>, <&dma 7>;
-                       dma-names = "tx", "rx";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        status = "disabled";
                };
 
-               pixelvalve@7e206000 {
-                       compatible = "brcm,bcm2835-pixelvalve0";
-                       reg = <0x7e206000 0x100>;
-                       interrupts = <2 13>; /* pwa0 */
-               };
-
-               pixelvalve@7e207000 {
-                       compatible = "brcm,bcm2835-pixelvalve1";
-                       reg = <0x7e207000 0x100>;
-                       interrupts = <2 14>; /* pwa1 */
-               };
-
                dpi: dpi@7e208000 {
                        compatible = "brcm,bcm2835-dpi";
                        reg = <0x7e208000 0x8c>;
 
                };
 
-               thermal: thermal@7e212000 {
-                       compatible = "brcm,bcm2835-thermal";
-                       reg = <0x7e212000 0x8>;
-                       clocks = <&clocks BCM2835_CLOCK_TSENS>;
-                       #thermal-sensor-cells = <0>;
-                       status = "disabled";
-               };
-
                aux: aux@7e215000 {
                        compatible = "brcm,bcm2835-aux";
                        #clock-cells = <1>;
                        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";
-               };
-
                vec: vec@7e806000 {
                        compatible = "brcm,bcm2835-vec";
                        reg = <0x7e806000 0x1000>;
                        status = "disabled";
                };
 
-               pixelvalve@7e807000 {
-                       compatible = "brcm,bcm2835-pixelvalve2";
-                       reg = <0x7e807000 0x100>;
-                       interrupts = <2 10>; /* pixelvalve */
-               };
-
-               hdmi: hdmi@7e902000 {
-                       compatible = "brcm,bcm2835-hdmi";
-                       reg = <0x7e902000 0x600>,
-                             <0x7e808000 0x100>;
-                       interrupts = <2 8>, <2 9>;
-                       ddc = <&i2c2>;
-                       clocks = <&clocks BCM2835_PLLH_PIX>,
-                                <&clocks BCM2835_CLOCK_HSM>;
-                       clock-names = "pixel", "hdmi";
-                       dmas = <&dma 17>;
-                       dma-names = "audio-rx";
-                       status = "disabled";
-               };
-
                usb: usb@7e980000 {
                        compatible = "brcm,bcm2835-usb";
                        reg = <0x7e980000 0x10000>;
                        phys = <&usbphy>;
                        phy-names = "usb2-phy";
                };
-
-               v3d: v3d@7ec00000 {
-                       compatible = "brcm,bcm2835-v3d";
-                       reg = <0x7ec00000 0x1000>;
-                       interrupts = <1 10>;
-                       power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
-               };
-
-               vc4: gpu {
-                       compatible = "brcm,bcm2835-vc4";
-               };
        };
 
        clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
                /* The oscillator is the root of the clock tree. */
-               clk_osc: clock@3 {
+               clk_osc: clk-osc {
                        compatible = "fixed-clock";
-                       reg = <3>;
                        #clock-cells = <0>;
                        clock-output-names = "osc";
                        clock-frequency = <19200000>;
                };
 
-               clk_usb: clock@4 {
+               clk_usb: clk-usb {
                        compatible = "fixed-clock";
-                       reg = <4>;
                        #clock-cells = <0>;
                        clock-output-names = "otg";
                        clock-frequency = <480000000>;
diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
new file mode 100644 (file)
index 0000000..3343253
--- /dev/null
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2019 Legrand AV Inc.
+ */
+
+/dts-v1/;
+
+#include "bcm47094.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+/ {
+       compatible = "luxul,xwc-2000-v1", "brcm,bcm47094", "brcm,bcm4708";
+       model = "Luxul XWC-2000 V1";
+
+       chosen {
+               bootargs = "earlycon";
+       };
+
+       memory {
+               reg = <0x00000000 0x08000000
+                      0x88000000 0x18000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               status  {
+                       label = "bcm53xx:green:status";
+                       gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "timer";
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               restart {
+                       label = "Reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&spi_nor {
+       status = "okay";
+};
index 372dc1e..2d9b4dd 100644 (file)
        mdio: mdio@18003000 {
                compatible = "brcm,iproc-mdio";
                reg = <0x18003000 0x8>;
-               #size-cells = <1>;
-               #address-cells = <0>;
+               #size-cells = <0>;
+               #address-cells = <1>;
        };
 
        mdio-bus-mux@18003000 {
index 2e8a397..3081b04 100644 (file)
                                status = "disabled";
                        };
 
-                       crypto_sram: sa-sram@ffffe000 {
+                       crypto_sram: sram@ffffe000 {
                                compatible = "mmio-sram";
                                reg = <0xffffe000 0x800>;
                                clocks = <&gate_clk 15>;
index 37e0487..7e7aa10 100644 (file)
 
                target-module@f4000 {                   /* 0x4a0f4000, ap 23 04.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox1";
                        reg = <0xf4000 0x4>,
                              <0xf4010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@90000 {                   /* 0x48090000, ap 55 12.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "rng";
                        reg = <0x91fe0 0x4>,
                              <0x91fe4 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@b2000 {                   /* 0x480b2000, ap 37 52.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "hdq1w";
                        reg = <0xb2000 0x4>,
                              <0xb2014 0x4>,
                              <0xb2018 0x4>;
 
                                davinci_mdio: mdio@1000 {
                                        compatible = "ti,cpsw-mdio","ti,davinci_mdio";
-                                       clocks = <&gmac_clkctrl DRA7_GMAC_GMAC_CLKCTRL 0>;
+                                       clocks = <&gmac_main_clk>;
                                        clock-names = "fck";
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                target-module@2000 {                    /* 0x48802000, ap 95 7c.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox13";
                        reg = <0x2000 0x4>,
                              <0x2010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3a000 {                   /* 0x4883a000, ap 33 3e.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox2";
                        reg = <0x3a000 0x4>,
                              <0x3a010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3c000 {                   /* 0x4883c000, ap 35 3a.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox3";
                        reg = <0x3c000 0x4>,
                              <0x3c010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3e000 {                   /* 0x4883e000, ap 37 46.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox4";
                        reg = <0x3e000 0x4>,
                              <0x3e010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@40000 {                   /* 0x48840000, ap 39 64.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox5";
                        reg = <0x40000 0x4>,
                              <0x40010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@42000 {                   /* 0x48842000, ap 41 4e.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox6";
                        reg = <0x42000 0x4>,
                              <0x42010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@44000 {                   /* 0x48844000, ap 43 42.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox7";
                        reg = <0x44000 0x4>,
                              <0x44010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@46000 {                   /* 0x48846000, ap 45 48.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox8";
                        reg = <0x46000 0x4>,
                              <0x46010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@5e000 {                   /* 0x4885e000, ap 69 6c.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox9";
                        reg = <0x5e000 0x4>,
                              <0x5e010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@60000 {                   /* 0x48860000, ap 71 4a.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox10";
                        reg = <0x60000 0x4>,
                              <0x60010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@62000 {                   /* 0x48862000, ap 73 74.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox11";
                        reg = <0x62000 0x4>,
                              <0x62010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@64000 {                   /* 0x48864000, ap 67 52.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox12";
                        reg = <0x64000 0x4>,
                              <0x64010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@4000 {                    /* 0x4ae14000, ap 7 28.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "wd_timer2";
                        reg = <0x4000 0x4>,
                              <0x4010 0x4>,
                              <0x4014 0x4>;
index 953f0ff..73e5011 100644 (file)
 
 #include "dra7-l4.dtsi"
 #include "dra7xx-clocks.dtsi"
+
+&prm {
+       prm_dsp1: prm@400 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x400 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_ipu: prm@500 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x500 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_core: prm@700 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x700 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_iva: prm@f00 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0xf00 0x100>;
+       };
+
+       prm_dsp2: prm@1b00 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1b00 0x40>;
+               #reset-cells = <1>;
+       };
+
+       prm_eve1: prm@1b40 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1b40 0x40>;
+       };
+
+       prm_eve2: prm@1b80 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1b80 0x40>;
+       };
+
+       prm_eve3: prm@1bc0 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1bc0 0x40>;
+       };
+
+       prm_eve4: prm@1c00 {
+               compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1c00 0x60>;
+       };
+};
diff --git a/arch/arm/boot/dts/e60k02.dtsi b/arch/arm/boot/dts/e60k02.dtsi
new file mode 100644 (file)
index 0000000..5a2c532
--- /dev/null
@@ -0,0 +1,301 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Andreas Kemnade
+ * based on works
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * and
+ * Copyright (C) 2014 Ricoh Electronic Devices Co., Ltd
+ *
+ * Netronix E60K02 board common.
+ * This board is equipped with different SoCs and
+ * found in ebook-readers like the Kobo Clara HD (with i.MX6SLL) and
+ * the Tolino Shine 3 (with i.MX6SL)
+ */
+#include <dt-bindings/input/input.h>
+
+/ {
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       gpio_keys: gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "Power";
+                       gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+
+               cover {
+                       label = "Cover";
+                       gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
+                       linux,code = <SW_LID>;
+                       linux,input-type = <EV_SW>;
+                       wakeup-source;
+               };
+       };
+
+       leds: leds {
+               compatible = "gpio-leds";
+
+               on {
+                       label = "e60k02:white:on";
+                       gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "timer";
+               };
+       };
+
+       memory {
+               reg = <0x80000000 0x20000000>;
+       };
+
+       reg_wifi: regulator-wifi {
+               compatible = "regulator-fixed";
+               regulator-name = "SD3_SPWR";
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+               gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       wifi_pwrseq: wifi_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               post-power-on-delay-ms = <20>;
+               reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+       };
+};
+
+
+&i2c1 {
+       clock-frequency = <100000>;
+       status = "okay";
+
+       lm3630a: backlight@36 {
+               reg = <0x36>;
+               compatible = "ti,lm3630a";
+               enable-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               led@0 {
+                       reg = <0>;
+                       led-sources = <0>;
+                       label = "backlight_warm";
+                       default-brightness = <0>;
+                       max-brightness = <255>;
+               };
+
+               led@1 {
+                       reg = <1>;
+                       led-sources = <1>;
+                       label = "backlight_cold";
+                       default-brightness = <0>;
+                       max-brightness = <255>;
+               };
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       status = "okay";
+
+       /* TODO: CYTTSP5 touch controller at 0x24 */
+
+       /* TODO: TPS65185 PMIC for E Ink at 0x68 */
+
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       status = "okay";
+
+       ricoh619: pmic@32 {
+               compatible = "ricoh,rc5t619";
+               reg = <0x32>;
+               system-power-controller;
+
+               regulators {
+                       dcdc1_reg: DCDC1 {
+                               regulator-name = "DCDC1";
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-max-microvolt = <900000>;
+                                       regulator-suspend-min-microvolt = <900000>;
+                               };
+                       };
+
+                       /* Core3_3V3 */
+                       dcdc2_reg: DCDC2 {
+                               regulator-name = "DCDC2";
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-max-microvolt = <3300000>;
+                                       regulator-suspend-min-microvolt = <3300000>;
+                               };
+                       };
+
+                       dcdc3_reg: DCDC3 {
+                               regulator-name = "DCDC3";
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-max-microvolt = <1140000>;
+                                       regulator-suspend-min-microvolt = <1140000>;
+                               };
+                       };
+
+                       /* Core4_1V2 */
+                       dcdc4_reg: DCDC4 {
+                               regulator-name = "DCDC4";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-max-microvolt = <1140000>;
+                                       regulator-suspend-min-microvolt = <1140000>;
+                               };
+                       };
+
+                       /* Core4_1V8 */
+                       dcdc5_reg: DCDC5 {
+                               regulator-name = "DCDC5";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-max-microvolt = <1700000>;
+                                       regulator-suspend-min-microvolt = <1700000>;
+                               };
+                       };
+
+                       /* IR_3V3 */
+                       ldo1_reg: LDO1  {
+                               regulator-name = "LDO1";
+                               regulator-boot-on;
+                       };
+
+                       /* Core1_3V3 */
+                       ldo2_reg: LDO2  {
+                               regulator-name = "LDO2";
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-max-microvolt = <3000000>;
+                                       regulator-suspend-min-microvolt = <3000000>;
+                               };
+                       };
+
+                       /* Core5_1V2 */
+                       ldo3_reg: LDO3  {
+                               regulator-name = "LDO3";
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       ldo4_reg: LDO4 {
+                               regulator-name = "LDO4";
+                               regulator-boot-on;
+                       };
+
+                       /* SPD_3V3 */
+                       ldo5_reg: LDO5 {
+                               regulator-name = "LDO5";
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       /* DDR_0V6 */
+                       ldo6_reg: LDO6 {
+                               regulator-name = "LDO6";
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       /* VDD_PWM */
+                       ldo7_reg: LDO7 {
+                               regulator-name = "LDO7";
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       /* ldo_1v8 */
+                       ldo8_reg: LDO8 {
+                               regulator-name = "LDO8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       ldo9_reg: LDO9 {
+                               regulator-name = "LDO9";
+                               regulator-boot-on;
+                       };
+
+                       ldo10_reg: LDO10 {
+                               regulator-name = "LDO10";
+                               regulator-boot-on;
+                       };
+
+                       ldortc1_reg: LDORTC1  {
+                               regulator-name = "LDORTC1";
+                               regulator-boot-on;
+                       };
+               };
+       };
+};
+
+&snvs_rtc {
+       /* we are using the rtc in the pmic, not disabled in imx6sll.dtsi */
+       status = "disabled";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&usdhc2 {
+       non-removable;
+       status = "okay";
+};
+
+&usdhc3 {
+       vmmc-supply = <&reg_wifi>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       cap-power-off-card;
+       non-removable;
+       status = "okay";
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       disable-over-current;
+       srp-disable;
+       hnp-disable;
+       adp-disable;
+       status = "okay";
+};
index 67d8601..96678dd 100644 (file)
                interrupt-controller;
                #interrupt-cells = <2>;
        };
+
        gpio1: gpio@e0050080 {
                compatible = "renesas,em-gio";
                reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>;
                interrupt-controller;
                #interrupt-cells = <2>;
        };
+
        gpio2: gpio@e0050100 {
                compatible = "renesas,em-gio";
                reg = <0xe0050100 0x2c>, <0xe0050140 0x20>;
                interrupt-controller;
                #interrupt-cells = <2>;
        };
+
        gpio3: gpio@e0050180 {
                compatible = "renesas,em-gio";
                reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>;
                interrupt-controller;
                #interrupt-cells = <2>;
        };
+
        gpio4: gpio@e0050200 {
                compatible = "renesas,em-gio";
                reg = <0xe0050200 0x2c>, <0xe0050240 0x20>;
index 7848184..b016b0b 100644 (file)
                #size-cells = <1>;
                ranges;
 
-               sysram@2020000 {
+               sram@2020000 {
                        compatible = "mmio-sram";
                        reg = <0x02020000 0x40000>;
                        #address-cells = <1>;
                                        (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
                };
 
-               mct@10050000 {
+               timer@10050000 {
                        compatible = "samsung,exynos4210-mct";
                        reg = <0x10050000 0x800>;
                        interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
                sysmmu_jpeg: sysmmu@11a60000 {
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x11a60000 0x1000>;
-                       interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "sysmmu", "master";
                        clocks = <&cmu CLK_SMMUJPEG>, <&cmu CLK_JPEG>;
                        power-domains = <&pd_cam>;
                sysmmu_fimd0: sysmmu@11e20000 {
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x11e20000 0x1000>;
-                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "sysmmu", "master";
                        clocks = <&cmu CLK_SMMUFIMD0>, <&cmu CLK_FIMD0>;
                        power-domains = <&pd_lcd0>;
                sysmmu_mfc: sysmmu@13620000 {
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x13620000 0x1000>;
-                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "sysmmu", "master";
                        clocks = <&cmu CLK_SMMUMFC_L>, <&cmu CLK_MFC>;
                        power-domains = <&pd_mfc>;
index 433f109..d2779a7 100644 (file)
                        syscon = <&pmu_system_controller>;
                };
 
-               pd_mfc: mfc-power-domain@10023c40 {
+               pd_mfc: power-domain@10023c40 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023C40 0x20>;
                        #power-domain-cells = <0>;
                        label = "MFC";
                };
 
-               pd_g3d: g3d-power-domain@10023c60 {
+               pd_g3d: power-domain@10023c60 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023C60 0x20>;
                        #power-domain-cells = <0>;
                        label = "G3D";
                };
 
-               pd_lcd0: lcd0-power-domain@10023c80 {
+               pd_lcd0: power-domain@10023c80 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023C80 0x20>;
                        #power-domain-cells = <0>;
                        label = "LCD0";
                };
 
-               pd_tv: tv-power-domain@10023c20 {
+               pd_tv: power-domain@10023c20 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023C20 0x20>;
                        #power-domain-cells = <0>;
                        label = "TV";
                };
 
-               pd_cam: cam-power-domain@10023c00 {
+               pd_cam: power-domain@10023c00 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023C00 0x20>;
                        #power-domain-cells = <0>;
                        label = "CAM";
                };
 
-               pd_gps: gps-power-domain@10023ce0 {
+               pd_gps: power-domain@10023ce0 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023CE0 0x20>;
                        #power-domain-cells = <0>;
                        label = "GPS";
                };
 
-               pd_gps_alive: gps-alive-power-domain@10023d00 {
+               pd_gps_alive: power-domain@10023d00 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023D00 0x20>;
                        #power-domain-cells = <0>;
index f220716..554819a 100644 (file)
@@ -72,7 +72,7 @@
        };
 
        soc: soc {
-               sysram: sysram@2020000 {
+               sysram: sram@2020000 {
                        compatible = "mmio-sram";
                        reg = <0x02020000 0x20000>;
                        #address-cells = <1>;
@@ -90,7 +90,7 @@
                        };
                };
 
-               pd_lcd1: lcd1-power-domain@10023ca0 {
+               pd_lcd1: power-domain@10023ca0 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023CA0 0x20>;
                        #power-domain-cells = <0>;
                        arm,data-latency = <2 2 1>;
                };
 
-               mct: mct@10050000 {
+               mct: timer@10050000 {
                        compatible = "samsung,exynos4210-mct";
                        reg = <0x10050000 0x800>;
-                       interrupt-parent = <&mct_map>;
-                       interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
                        clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
                        clock-names = "fin_pll", "mct";
-
-                       mct_map: mct-map {
-                               #interrupt-cells = <1>;
-                               #address-cells = <0>;
-                               #size-cells = <0>;
-                               interrupt-map =
-                                       <0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
-                                       <1 &gic 0 69 IRQ_TYPE_LEVEL_HIGH>,
-                                       <2 &combiner 12 6>,
-                                       <3 &combiner 12 7>,
-                                       <4 &gic 0 42 IRQ_TYPE_LEVEL_HIGH>,
-                                       <5 &gic 0 48 IRQ_TYPE_LEVEL_HIGH>;
-                       };
+                       interrupts-extended = <&gic GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&combiner 12 6>,
+                                             <&combiner 12 7>,
+                                             <&gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                watchdog: watchdog@10060000 {
index d20db2d..5022aa5 100644 (file)
                        interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
                };
 
-               sysram@2020000 {
+               sram@2020000 {
                        compatible = "mmio-sram";
                        reg = <0x02020000 0x40000>;
                        #address-cells = <1>;
                        };
                };
 
-               pd_isp: isp-power-domain@10023ca0 {
+               pd_isp: power-domain@10023ca0 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10023CA0 0x20>;
                        #power-domain-cells = <0>;
                        clock-names = "aclk200", "aclk400_mcuisp";
                };
 
-               mct@10050000 {
+               timer@10050000 {
                        compatible = "samsung,exynos4412-mct";
                        reg = <0x10050000 0x800>;
-                       interrupt-parent = <&mct_map>;
-                       interrupts = <0>, <1>, <2>, <3>, <4>;
                        clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
                        clock-names = "fin_pll", "mct";
-
-                       mct_map: mct-map {
-                               #interrupt-cells = <1>;
-                               #address-cells = <0>;
-                               #size-cells = <0>;
-                               interrupt-map =
-                                       <0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
-                                       <1 &combiner 12 5>,
-                                       <2 &combiner 12 6>,
-                                       <3 &combiner 12 7>,
-                                       <4 &gic 1 12 IRQ_TYPE_LEVEL_HIGH>;
-                       };
+                       interrupts-extended = <&gic GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&combiner 12 5>,
+                                             <&combiner 12 6>,
+                                             <&combiner 12 7>,
+                                             <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                watchdog: watchdog@10060000 {
index 67f9b45..4801ca7 100644 (file)
@@ -35,8 +35,8 @@
                #size-cells = <1>;
                ranges;
 
-               chipid@10000000 {
-                       compatible = "samsung,exynos4210-chipid";
+               chipid: chipid@10000000 {
+                       compatible = "samsung,exynos4210-chipid", "syscon";
                        reg = <0x10000000 0x100>;
                };
 
index 6fcb78a..d6c85ef 100644 (file)
@@ -11,6 +11,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/clock/samsung,s2mps11.h>
+#include <dt-bindings/sound/samsung-i2s.h>
 #include "exynos5250.dtsi"
 
 / {
                };
        };
 
+       sound {
+               compatible = "samsung,arndale-wm1811";
+               samsung,audio-cpu = <&i2s0>;
+               samsung,audio-codec = <&wm1811>;
+       };
+
        fixed-rate-clocks {
                xxti {
                        compatible = "samsung,clock-xxti";
        };
 };
 
+&clock {
+       assigned-clocks = <&clock CLK_FOUT_EPLL>;
+       assigned-clock-rates = <49152000>;
+};
+
+&clock_audss {
+       assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>;
+       assigned-clock-parents = <&clock CLK_FOUT_EPLL>;
+};
+
 &cpu0 {
        cpu0-supply = <&buck2_reg>;
 };
 &i2c_3 {
        status = "okay";
 
-       wm1811a@1a {
+       wm1811: codec@1a {
                compatible = "wlf,wm1811";
                reg = <0x1a>;
+               clocks = <&i2s0 CLK_I2S_CDCLK>;
+               clock-names = "MCLK1";
 
                AVDD2-supply = <&main_dc_reg>;
                CPVDD-supply = <&main_dc_reg>;
 };
 
 &i2s0 {
+       assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>;
+       assigned-clock-parents = <&clock_audss EXYNOS_I2S_BUS>;
        status = "okay";
 };
 
+&i2s0_bus {
+       samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+};
+
 &mali {
        mali-supply = <&buck4_reg>;
        status = "okay";
index fc966c1..e1f0215 100644 (file)
        };
 
        soc: soc {
-               sysram@2020000 {
+               sram@2020000 {
                        compatible = "mmio-sram";
                        reg = <0x02020000 0x30000>;
                        #address-cells = <1>;
                        power-domains = <&pd_mau>;
                };
 
-               mct@101c0000 {
+               timer@101c0000 {
                        compatible = "samsung,exynos4210-mct";
                        reg = <0x101C0000 0x800>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-                       interrupt-parent = <&mct_map>;
-                       interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
-                                    <4 0>, <5 0>;
                        clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
                        clock-names = "fin_pll", "mct";
-
-                       mct_map: mct-map {
-                               #interrupt-cells = <2>;
-                               #address-cells = <0>;
-                               #size-cells = <0>;
-                               interrupt-map = <0x0 0 &combiner 23 3>,
-                                               <0x1 0 &combiner 23 4>,
-                                               <0x2 0 &combiner 25 2>,
-                                               <0x3 0 &combiner 25 3>,
-                                               <0x4 0 &gic 0 120 IRQ_TYPE_LEVEL_HIGH>,
-                                               <0x5 0 &gic 0 121 IRQ_TYPE_LEVEL_HIGH>;
-                       };
+                       interrupts-extended = <&combiner 23 3>,
+                                             <&combiner 23 4>,
+                                             <&combiner 25 2>,
+                                             <&combiner 25 3>,
+                                             <&gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                pinctrl_0: pinctrl@11400000 {
                        compatible = "samsung,s5pv210-i2s";
                        status = "disabled";
                        reg = <0x03830000 0x100>;
-                       dmas = <&pdma0 10
-                               &pdma0 9
-                               &pdma0 8>;
+                       dmas = <&pdma0 10>,
+                               <&pdma0 9>,
+                               <&pdma0 8>;
                        dma-names = "tx", "rx", "tx-sec";
                        clocks = <&clock_audss EXYNOS_I2S_BUS>,
                                <&clock_audss EXYNOS_I2S_BUS>,
                        compatible = "samsung,s3c6410-i2s";
                        status = "disabled";
                        reg = <0x12D60000 0x100>;
-                       dmas = <&pdma1 12
-                               &pdma1 11>;
+                       dmas = <&pdma1 12>,
+                               <&pdma1 11>;
                        dma-names = "tx", "rx";
                        clocks = <&clock CLK_I2S1>, <&clock CLK_DIV_I2S1>;
                        clock-names = "iis", "i2s_opclk0";
                        compatible = "samsung,s3c6410-i2s";
                        status = "disabled";
                        reg = <0x12D70000 0x100>;
-                       dmas = <&pdma0 12
-                               &pdma0 11>;
+                       dmas = <&pdma0 12>,
+                               <&pdma0 11>;
                        dma-names = "tx", "rx";
                        clocks = <&clock CLK_I2S2>, <&clock CLK_DIV_I2S2>;
                        clock-names = "iis", "i2s_opclk0";
index 3581b57..b0811db 100644 (file)
                        reg = <0x10000000 0x100>;
                };
 
-               mct: mct@100b0000 {
+               mct: timer@100b0000 {
                        compatible = "samsung,exynos4210-mct";
                        reg = <0x100B0000 0x1000>;
                        clocks = <&fin_pll>, <&clock_peri PERI_CLK_MCT>;
index e6f78b1..a4b03d4 100644 (file)
                audi2s0: i2s@3830000 {
                        compatible = "samsung,exynos5420-i2s";
                        reg = <0x03830000 0x100>;
-                       dmas = <&pdma0 10
-                               &pdma0 9
-                               &pdma0 8>;
+                       dmas = <&pdma0 10>,
+                               <&pdma0 9>,
+                               <&pdma0 8>;
                        dma-names = "tx", "rx", "tx-sec";
                        clocks = <&clock_audss EXYNOS_I2S_BUS>,
                                <&clock_audss EXYNOS_I2S_BUS>,
index 9eb48ca..2bcbdf8 100644 (file)
        status = "okay";
 };
 
+&timer {
+       arm,cpu-registers-not-fw-configured;
+};
+
 &tmu_cpu0 {
        vtmu-supply = <&ldo10_reg>;
 };
index 7d51e0f..d39907a 100644 (file)
                };
 
                clock: clock-controller@10010000 {
-                       compatible = "samsung,exynos5420-clock";
+                       compatible = "samsung,exynos5420-clock", "syscon";
                        reg = <0x10010000 0x30000>;
                        #clock-cells = <1>;
                };
                        status = "disabled";
                };
 
+               dmc: memory-controller@10c20000 {
+                       compatible = "samsung,exynos5422-dmc";
+                       reg = <0x10c20000 0x10000>, <0x10c30000 0x10000>;
+                       interrupt-parent = <&combiner>;
+                       interrupts = <16 0>, <16 1>;
+                       interrupt-names = "drex_0", "drex_1";
+                       clocks = <&clock CLK_FOUT_SPLL>,
+                                <&clock CLK_MOUT_SCLK_SPLL>,
+                                <&clock CLK_FF_DOUT_SPLL2>,
+                                <&clock CLK_FOUT_BPLL>,
+                                <&clock CLK_MOUT_BPLL>,
+                                <&clock CLK_SCLK_BPLL>,
+                                <&clock CLK_MOUT_MX_MSPLL_CCORE>,
+                                <&clock CLK_MOUT_MCLK_CDREX>;
+                       clock-names = "fout_spll",
+                                     "mout_sclk_spll",
+                                     "ff_dout_spll2",
+                                     "fout_bpll",
+                                     "mout_bpll",
+                                     "sclk_bpll",
+                                     "mout_mx_mspll_ccore",
+                                     "mout_mclk_cdrex";
+                       samsung,syscon-clk = <&clock>;
+                       status = "disabled";
+               };
+
                nocp_mem0_0: nocp@10ca1000 {
                        compatible = "samsung,exynos5420-nocp";
                        reg = <0x10CA1000 0x200>;
                        status = "disabled";
                };
 
+               ppmu_dmc0_0: ppmu@10d00000 {
+                       compatible = "samsung,exynos-ppmu";
+                       reg = <0x10d00000 0x2000>;
+                       clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
+                       clock-names = "ppmu";
+                       events {
+                               ppmu_event3_dmc0_0: ppmu-event3-dmc0_0 {
+                                       event-name = "ppmu-event3-dmc0_0";
+                               };
+                       };
+               };
+
+               ppmu_dmc0_1: ppmu@10d10000 {
+                       compatible = "samsung,exynos-ppmu";
+                       reg = <0x10d10000 0x2000>;
+                       clocks = <&clock CLK_PCLK_PPMU_DREX0_1>;
+                       clock-names = "ppmu";
+                       events {
+                               ppmu_event3_dmc0_1: ppmu-event3-dmc0_1 {
+                                       event-name = "ppmu-event3-dmc0_1";
+                               };
+                       };
+               };
+
+               ppmu_dmc1_0: ppmu@10d60000 {
+                       compatible = "samsung,exynos-ppmu";
+                       reg = <0x10d60000 0x2000>;
+                       clocks = <&clock CLK_PCLK_PPMU_DREX1_0>;
+                       clock-names = "ppmu";
+                       events {
+                               ppmu_event3_dmc1_0: ppmu-event3-dmc1_0 {
+                                       event-name = "ppmu-event3-dmc1_0";
+                               };
+                       };
+               };
+
+               ppmu_dmc1_1: ppmu@10d70000 {
+                       compatible = "samsung,exynos-ppmu";
+                       reg = <0x10d70000 0x2000>;
+                       clocks = <&clock CLK_PCLK_PPMU_DREX1_1>;
+                       clock-names = "ppmu";
+                       events {
+                               ppmu_event3_dmc1_1: ppmu-event3-dmc1_1 {
+                                       event-name = "ppmu-event3-dmc1_1";
+                               };
+                       };
+               };
+
                gsc_pd: power-domain@10044000 {
                        compatible = "samsung,exynos4210-pd";
                        reg = <0x10044000 0x20>;
                i2s0: i2s@3830000 {
                        compatible = "samsung,exynos5420-i2s";
                        reg = <0x03830000 0x100>;
-                       dmas = <&adma 0
-                               &adma 2
-                               &adma 1>;
+                       dmas = <&adma 0>,
+                               <&adma 2>,
+                               <&adma 1>;
                        dma-names = "tx", "rx", "tx-sec";
                        clocks = <&clock_audss EXYNOS_I2S_BUS>,
                                <&clock_audss EXYNOS_I2S_BUS>,
                i2s1: i2s@12d60000 {
                        compatible = "samsung,exynos5420-i2s";
                        reg = <0x12D60000 0x100>;
-                       dmas = <&pdma1 12
-                               &pdma1 11>;
+                       dmas = <&pdma1 12>,
+                               <&pdma1 11>;
                        dma-names = "tx", "rx";
                        clocks = <&clock CLK_I2S1>, <&clock CLK_SCLK_I2S1>;
                        clock-names = "iis", "i2s_opclk0";
                i2s2: i2s@12d70000 {
                        compatible = "samsung,exynos5420-i2s";
                        reg = <0x12D70000 0x100>;
-                       dmas = <&pdma0 12
-                               &pdma0 11>;
+                       dmas = <&pdma0 12>,
+                               <&pdma0 11>;
                        dma-names = "tx", "rx";
                        clocks = <&clock CLK_I2S2>, <&clock CLK_SCLK_I2S2>;
                        clock-names = "iis", "i2s_opclk0";
index 829147e..059fa32 100644 (file)
                        clock-frequency = <24000000>;
                };
        };
+
+       dmc_opp_table: opp_table2 {
+               compatible = "operating-points-v2";
+
+               opp00 {
+                       opp-hz = /bits/ 64 <165000000>;
+                       opp-microvolt = <875000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <206000000>;
+                       opp-microvolt = <875000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <275000000>;
+                       opp-microvolt = <875000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <413000000>;
+                       opp-microvolt = <887500>;
+               };
+               opp04 {
+                       opp-hz = /bits/ 64 <543000000>;
+                       opp-microvolt = <937500>;
+               };
+               opp05 {
+                       opp-hz = /bits/ 64 <633000000>;
+                       opp-microvolt = <1012500>;
+               };
+               opp06 {
+                       opp-hz = /bits/ 64 <728000000>;
+                       opp-microvolt = <1037500>;
+               };
+               opp07 {
+                       opp-hz = /bits/ 64 <825000000>;
+                       opp-microvolt = <1050000>;
+               };
+       };
+
+       samsung_K3QF2F20DB: lpddr3 {
+               compatible      = "samsung,K3QF2F20DB", "jedec,lpddr3";
+               density         = <16384>;
+               io-width        = <32>;
+               #address-cells  = <1>;
+               #size-cells     = <0>;
+
+               tRFC-min-tck            = <17>;
+               tRRD-min-tck            = <2>;
+               tRPab-min-tck           = <2>;
+               tRPpb-min-tck           = <2>;
+               tRCD-min-tck            = <3>;
+               tRC-min-tck             = <6>;
+               tRAS-min-tck            = <5>;
+               tWTR-min-tck            = <2>;
+               tWR-min-tck             = <7>;
+               tRTP-min-tck            = <2>;
+               tW2W-C2C-min-tck        = <0>;
+               tR2R-C2C-min-tck        = <0>;
+               tWL-min-tck             = <8>;
+               tDQSCK-min-tck          = <5>;
+               tRL-min-tck             = <14>;
+               tFAW-min-tck            = <5>;
+               tXSR-min-tck            = <12>;
+               tXP-min-tck             = <2>;
+               tCKE-min-tck            = <2>;
+               tCKESR-min-tck          = <2>;
+               tMRD-min-tck            = <5>;
+
+               timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
+                       compatible      = "jedec,lpddr3-timings";
+                       /* workaround: 'reg' shows max-freq */
+                       reg             = <800000000>;
+                       min-freq        = <100000000>;
+                       tRFC            = <65000>;
+                       tRRD            = <6000>;
+                       tRPab           = <12000>;
+                       tRPpb           = <12000>;
+                       tRCD            = <10000>;
+                       tRC             = <33750>;
+                       tRAS            = <23000>;
+                       tWTR            = <3750>;
+                       tWR             = <7500>;
+                       tRTP            = <3750>;
+                       tW2W-C2C        = <0>;
+                       tR2R-C2C        = <0>;
+                       tFAW            = <25000>;
+                       tXSR            = <70000>;
+                       tXP             = <3750>;
+                       tCKE            = <3750>;
+                       tCKESR          = <3750>;
+                       tMRD            = <7000>;
+               };
+       };
 };
 
 &adc {
        cpu-supply = <&buck2_reg>;
 };
 
+&dmc {
+       devfreq-events = <&ppmu_event3_dmc0_0>, <&ppmu_event3_dmc0_1>,
+                       <&ppmu_event3_dmc1_0>, <&ppmu_event3_dmc1_1>;
+       device-handle = <&samsung_K3QF2F20DB>;
+       operating-points-v2 = <&dmc_opp_table>;
+       vdd-supply = <&buck1_reg>;
+       status = "okay";
+};
+
 &hsi2c_4 {
        status = "okay";
 
        };
 };
 
+&ppmu_dmc0_0 {
+       status = "okay";
+};
+
+&ppmu_dmc0_1 {
+       status = "okay";
+};
+
+&ppmu_dmc1_0 {
+       status = "okay";
+};
+
+&ppmu_dmc1_1 {
+       status = "okay";
+};
+
 &tmu_cpu0 {
        vtmu-supply = <&ldo7_reg>;
 };
index c19b5a5..a31ca2e 100644 (file)
        status = "disabled";
 };
 
+&chipid {
+       samsung,asv-bin = <2>;
+};
+
 &pwm {
        /*
         * PWM 0 -- fan
index 9c3b63b..f78dee8 100644 (file)
                status = "disabled";
        };
 
+       timer: timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+               clock-frequency = <24000000>;
+       };
+
        soc: soc {
-               sysram@2020000 {
+               sram@2020000 {
                        compatible = "mmio-sram";
                        reg = <0x02020000 0x54000>;
                        #address-cells = <1>;
                        };
                };
 
-               mct: mct@101c0000 {
+               mct: timer@101c0000 {
                        compatible = "samsung,exynos4210-mct";
                        reg = <0x101c0000 0xb00>;
-                       interrupt-parent = <&mct_map>;
-                       interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>,
-                                       <8>, <9>, <10>, <11>;
-
-                       mct_map: mct-map {
-                               #interrupt-cells = <1>;
-                               #address-cells = <0>;
-                               #size-cells = <0>;
-                               interrupt-map = <0 &combiner 23 3>,
-                                               <1 &combiner 23 4>,
-                                               <2 &combiner 25 2>,
-                                               <3 &combiner 25 3>,
-                                               <4 &gic 0 120 IRQ_TYPE_LEVEL_HIGH>,
-                                               <5 &gic 0 121 IRQ_TYPE_LEVEL_HIGH>,
-                                               <6 &gic 0 122 IRQ_TYPE_LEVEL_HIGH>,
-                                               <7 &gic 0 123 IRQ_TYPE_LEVEL_HIGH>,
-                                               <8 &gic 0 128 IRQ_TYPE_LEVEL_HIGH>,
-                                               <9 &gic 0 129 IRQ_TYPE_LEVEL_HIGH>,
-                                               <10 &gic 0 130 IRQ_TYPE_LEVEL_HIGH>,
-                                               <11 &gic 0 131 IRQ_TYPE_LEVEL_HIGH>;
-                       };
+                       interrupts-extended = <&combiner 23 3>,
+                                             <&combiner 23 4>,
+                                             <&combiner 25 2>,
+                                             <&combiner 25 3>,
+                                             <&gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                watchdog: watchdog@101d0000 {
index 4398f2d..60ca3d6 100644 (file)
        status = "okay";
 };
 
+&timer {
+       arm,cpu-registers-not-fw-configured;
+};
+
 &tmu_cpu0 {
        vtmu-supply = <&ldo10_reg>;
 };
index de639ee..16177d8 100644 (file)
@@ -17,7 +17,7 @@
 };
 
 &clock {
-       compatible = "samsung,exynos5800-clock";
+       compatible = "samsung,exynos5800-clock", "syscon";
 };
 
 &cluster_a15_opp_table {
index 3652f55..f3464cf 100644 (file)
                        status = "disabled";
                };
 
-               iram: iram@ffff4c00 {
+               iram: sram@ffff4c00 {
                        compatible = "mmio-sram";
                        reg = <0xffff4c00 0xb400>;
                };
index d7f6fb7..6b62f07 100644 (file)
@@ -55,7 +55,7 @@
                interrupt-parent = <&avic>;
                ranges;
 
-               iram: iram@1fffc000 {
+               iram: sram@1fffc000 {
                        compatible = "mmio-sram";
                        reg = <0x1fffc000 0x4000>;
                        #address-cells = <1>;
index 0a4b9a5..dea86b9 100644 (file)
                interrupt-parent = <&tzic>;
                ranges;
 
-               iram: iram@1ffe0000 {
+               iram: sram@1ffe0000 {
                        compatible = "mmio-sram";
                        reg = <0x1ffe0000 0x20000>;
                };
index f00dda3..9b4efcd 100644 (file)
 
        display0: disp0 {
                compatible = "fsl,imx-parallel-display";
-               interface-pix-fmt = "rgb565";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_ipu_disp0>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
                status = "disabled";
-               display-timings {
-                       claawvga {
-                               native-mode;
-                               clock-frequency = <27000000>;
-                               hactive = <800>;
-                               vactive = <480>;
-                               hback-porch = <40>;
-                               hfront-porch = <60>;
-                               vback-porch = <10>;
-                               vfront-porch = <10>;
-                               hsync-len = <20>;
-                               vsync-len = <10>;
-                               hsync-active = <0>;
-                               vsync-active = <0>;
-                               de-active = <1>;
-                               pixelclk-active = <0>;
-                       };
-               };
 
-               port {
+               port@0 {
+                       reg = <0>;
+
                        display0_in: endpoint {
                                remote-endpoint = <&ipu_di0_disp0>;
                        };
                };
+
+               port@1 {
+                       reg = <1>;
+
+                       display_out: endpoint {
+                               remote-endpoint = <&panel_in>;
+                       };
+               };
        };
 
        gpio-keys {
                };
        };
 
+       panel {
+               compatible = "sii,43wvf1g";
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&display_out>;
+                       };
+               };
+       };
+
        regulators {
                compatible = "simple-bus";
                #address-cells = <1>;
index ee6263d..f34993a 100644 (file)
        };
 
        /*
-        * UART mode pin header configration
+        * UART mode pin header configuration
         * 3 - GPIO5[26], pull-down 100K
         * 4 - GPIO5[27], pull-down 100K
         * 5 - TX, pull-up 100K
index 6632e99..3dcce34 100644 (file)
@@ -1,49 +1,6 @@
-/*
- * Copyright 2015 Armadeus Systems
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this file; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Copyright 2015 Armadeus Systems <support@armadeus.com>
 
 /dts-v1/;
 #include "imx6dl.dtsi"
index 9a5d6c9..cd07562 100644 (file)
 &i2c3 {
        status = "okay";
 
+       /*
+        * Touchscreen is using SODIMM 28/30, also used for PWM<B>, PWM<C>,
+        * aka pwm2, pwm3. so if you enable touchscreen, disable the pwms
+        */
+       touchscreen@4a {
+               compatible = "atmel,maxtouch";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pcap_1>;
+               reg = <0x4a>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <9 IRQ_TYPE_EDGE_FALLING>;         /* SODIMM 28 */
+               reset-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;     /* SODIMM 30 */
+               status = "disabled";
+       };
+
        /* M41T0M6 real time clock on carrier board */
        rtc_i2c: rtc@68 {
                compatible = "st,m41t0";
        };
 };
 
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               &pinctrl_weim_gpio_1 &pinctrl_weim_gpio_2
+               &pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
+               &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
+               &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1
+       >;
+
+       pinctrl_pcap_1: pcap1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_9__GPIO1_IO09   0x1b0b0 /* SODIMM 28 */
+                       MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x1b0b0 /* SODIMM 30 */
+               >;
+       };
+
+       pinctrl_mxt_ts: mxttsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_CS1__GPIO2_IO24  0x130b0 /* SODIMM 107 */
+                       MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x130b0 /* SODIMM 106 */
+               >;
+       };
+};
+
 &ipu1_di0_disp0 {
        remote-endpoint = <&lcd_display_in>;
 };
index e8d800f..80ed5f1 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/pwm/pwm.h>
 
 / {
        clock-frequency = <100000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c3>;
-       status = "disabled";
+       status = "okay";
 
        oled: oled@3d {
                compatible = "solomon,ssd1305fb-i2c";
                vcc-supply = <&sw2_reg>;
                status = "disabled";
        };
+
+       touchkeys: keys@5a {
+               compatible = "fsl,mpr121-touchkey";
+               reg = <0x5a>;
+               vdd-supply = <&sw2_reg>;
+               autorepeat;
+               linux,keycodes = <KEY_1>, <KEY_2>, <KEY_3>, <KEY_4>, <KEY_5>,
+                               <KEY_6>, <KEY_7>, <KEY_8>, <KEY_9>,
+                               <KEY_BACKSPACE>, <KEY_0>, <KEY_ENTER>;
+               poll-interval = <50>;
+               status = "disabled";
+       };
 };
 
 &iomuxc {
                >;
        };
 
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_7__UART2_TX_DATA        0x1b098
+                       MX6QDL_PAD_GPIO_8__UART2_RX_DATA        0x1b098
+               >;
+       };
+
        pinctrl_usbh1: usbh1grp {
                fsl,pins = <
                        MX6QDL_PAD_EIM_D30__USB_H1_OC   0x1b098
        status = "okay";
 };
 
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
 &usbh1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usbh1>;
index f979270..6010d3d 100644 (file)
        status = "okay";
 };
 
-&i2c3 {
-       status = "okay";
-};
-
 &leds {
        status = "okay";
 };
        status = "okay";
 };
 
+&touchkeys {
+       status = "okay";
+};
+
 &usdhc3 {
        status = "okay";
 };
index 2ed1031..008312e 100644 (file)
@@ -64,6 +64,7 @@
                                396000  1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6QDL_CLK_ARM>,
                                 <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
                                 <&clks IMX6QDL_CLK_STEP>,
index 0edd304..4665e15 100644 (file)
 &i2c1 {
        status = "okay";
 
+       /*
+        * Touchscreen is using SODIMM 28/30, also used for PWM<B>, PWM<C>,
+        * aka pwm2, pwm3. so if you enable touchscreen, disable the pwms
+        */
+       touchscreen@4a {
+               compatible = "atmel,maxtouch";
+               reg = <0x4a>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <10 IRQ_TYPE_EDGE_FALLING>;
+               reset-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* SODIMM 13 */
+               status = "disabled";
+       };
+
        pcie-switch@58 {
                compatible = "plx,pex8605";
                reg = <0x58>;
index b94bb68..a3fa04a 100644 (file)
 &i2c1 {
        status = "okay";
 
+       /*
+        * Touchscreen is using SODIMM 28/30, also used for PWM<B>, PWM<C>,
+        * aka pwm2, pwm3. so if you enable touchscreen, disable the pwms
+        */
+       touchscreen@4a {
+               compatible = "atmel,maxtouch";
+               reg = <0x4a>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <10 IRQ_TYPE_EDGE_FALLING>;
+               reset-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* SODIMM 13 */
+               status = "disabled";
+       };
+
        /* M41T0M6 real time clock on carrier board */
        rtc_i2c: rtc@68 {
                compatible = "st,m41t0";
index 302fd6a..5ba49d0 100644 (file)
 &i2c1 {
        status = "okay";
 
+       /*
+        * Touchscreen is using SODIMM 28/30, also used for PWM<B>, PWM<C>,
+        * aka pwm2, pwm3. so if you enable touchscreen, disable the pwms
+        */
+       touchscreen@4a {
+               compatible = "atmel,maxtouch";
+               reg = <0x4a>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <10 IRQ_TYPE_EDGE_FALLING>;
+               reset-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* SODIMM 13 */
+               status = "disabled";
+       };
+
        eeprom@50 {
                compatible = "atmel,24c02";
                reg = <0x50>;
index 07a36bb..664b0af 100644 (file)
@@ -1,49 +1,6 @@
-/*
- * Copyright 2015 Armadeus Systems
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this file; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Copyright 2015 Armadeus Systems <support@armadeus.com>
 
 /dts-v1/;
 #include "imx6q.dtsi"
index 9c61e3b..5219553 100644 (file)
        status = "okay";
 };
 
+&can1 {
+       status = "okay";
+};
+
+&can2 {
+       status = "disabled";
+};
+
 &hdmi {
        ddc-i2c-bus = <&i2c2>;
        status = "okay";
index 387801d..845cfad 100644 (file)
 &can1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_flexcan1>;
-       status = "okay";
 };
 
 &can2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_flexcan2>;
-       status = "okay";
 };
 
 &ecspi1 {
index ecc3989..d5d4690 100644 (file)
        sound-digital {
                compatible = "simple-audio-card";
                simple-audio-card,name = "tda1997x-audio";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,bitclock-master = <&sound_codec>;
+               simple-audio-card,frame-master = <&sound_codec>;
 
-               simple-audio-card,dai-link@0 {
-                       format = "i2s";
-
-                       cpu {
-                               sound-dai = <&ssi2>;
-                       };
+               sound_cpu: simple-audio-card,cpu {
+                       sound-dai = <&ssi2>;
+               };
 
-                       codec {
-                               bitclock-master;
-                               frame-master;
-                               sound-dai = <&hdmi_receiver>;
-                       };
+               sound_codec: simple-audio-card,codec {
+                       sound-dai = <&hdmi_receiver>;
                };
        };
 };
index d038f41..9d3be1c 100644 (file)
@@ -73,6 +73,7 @@
                                396000  1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6QDL_CLK_ARM>,
                                 <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
                                 <&clks IMX6QDL_CLK_STEP>,
                                396000  1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6QDL_CLK_ARM>,
                                 <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
                                 <&clks IMX6QDL_CLK_STEP>,
                                396000  1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6QDL_CLK_ARM>,
                                 <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
                                 <&clks IMX6QDL_CLK_STEP>,
index 7c4ad54..ff1287e 100644 (file)
 };
 
 &can1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_flexcan1>;
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&pinctrl_flexcan1_default>;
+       pinctrl-1 = <&pinctrl_flexcan1_sleep>;
        status = "disabled";
 };
 
 &can2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_flexcan2>;
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&pinctrl_flexcan2_default>;
+       pinctrl-1 = <&pinctrl_flexcan2_sleep>;
        status = "disabled";
 };
 
 /* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */
 &i2c1 {
        clock-frequency = <100000>;
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c1>;
+       pinctrl-1 = <&pinctrl_i2c1_gpio>;
+       scl-gpios = <&gpio5 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio5 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        status = "disabled";
 };
 
  */
 &i2c2 {
        clock-frequency = <100000>;
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c2>;
+       pinctrl-1 = <&pinctrl_i2c2_gpio>;
+       scl-gpios = <&gpio4 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio4 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        status = "okay";
 
        pmic: pfuze100@8 {
  */
 &i2c3 {
        clock-frequency = <100000>;
-       pinctrl-names = "default", "recovery";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c3>;
-       pinctrl-1 = <&pinctrl_i2c3_recovery>;
+       pinctrl-1 = <&pinctrl_i2c3_gpio>;
        scl-gpios = <&gpio3 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        sda-gpios = <&gpio3 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        status = "disabled";
                >;
        };
 
-       pinctrl_flexcan1: flexcan1grp {
+       pinctrl_flexcan1_default: flexcan1defgrp {
                fsl,pins = <
                        MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
                        MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
                >;
        };
 
-       pinctrl_flexcan2: flexcan2grp {
+       pinctrl_flexcan1_sleep: flexcan1slpgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x0
+                       MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0
+               >;
+       };
+
+       pinctrl_flexcan2_default: flexcan2defgrp {
                fsl,pins = <
                        MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0
                        MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0
                >;
        };
+       pinctrl_flexcan2_sleep: flexcan2slpgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x0
+                       MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x0
+               >;
+       };
 
        pinctrl_gpio_bl_on: gpioblon {
                fsl,pins = <
                >;
        };
 
+       pinctrl_i2c1_gpio: i2c1gpiogrp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x4001b8b1
+                       MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x4001b8b1
+               >;
+       };
+
        pinctrl_i2c2: i2c2grp {
                fsl,pins = <
                        MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
                >;
        };
 
+       pinctrl_i2c2_gpio: i2c2gpiogrp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x4001b8b1
+                       MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x4001b8b1
+               >;
+       };
+
        pinctrl_i2c3: i2c3grp {
                fsl,pins = <
                        MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
                >;
        };
 
-       pinctrl_i2c3_recovery: i2c3recoverygrp {
+       pinctrl_i2c3_gpio: i2c3gpiogrp {
                fsl,pins = <
                        MX6QDL_PAD_EIM_D17__GPIO3_IO17 0x4001b8b1
                        MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x4001b8b1
index 4738c3c..b78ed79 100644 (file)
@@ -1,66 +1,56 @@
-/*
- * Copyright 2015 Armadeus Systems
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this file; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Copyright 2015 Armadeus Systems <support@armadeus.com>
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
+/ {
+       reg_1p8v: regulator-1p8v {
+               compatible = "regulator-fixed";
+               regulator-name = "1P8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               vin-supply = <&reg_3p3v>;
+       };
+
+       usdhc1_pwrseq: usdhc1-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+               post-power-on-delay-ms = <15>;
+               power-off-delay-us = <70>;
+       };
+};
+
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii-id";
        phy-reset-duration = <10>;
        phy-reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
+       phy-handle = <&ethphy1>;
        status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy1: ethernet-phy@1 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <1>;
+                       interrupt-parent = <&gpio1>;
+                       interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+                       status = "okay";
+               };
+       };
 };
 
 /* Bluetooth */
 &uart2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart2>;
+       uart-has-rtscts;
        status = "okay";
 };
 
 &usdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc1>;
+       bus-width = <4>;
+       mmc-pwrseq = <&usdhc1_pwrseq>;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       cap-power-off-card;
+       keep-power-in-suspend;
        non-removable;
        status = "okay";
 
 };
 
 &iomuxc {
-       apf6 {
-               pinctrl_enet: enetgrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b8b0
-                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
-                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
-                               MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24       0x130b0
-                               MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28       0x130b0
-                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b030
-                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b030
-                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b030
-                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b030
-                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b030
-                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b030
-                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x13030
-                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b030
-                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x13030
-                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1f030
-                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1f030
-                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x13030
-                       >;
-               };
+       pinctrl_enet: enetgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b8b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                       MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24       0x130b0
+                       MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28       0x130b0
+                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b030
+                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b030
+                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b030
+                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b030
+                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b030
+                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b030
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x13030
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b030
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x13030
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1f030
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1f030
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x13030
+               >;
+       };
 
-               pinctrl_uart2: uart2grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b0
-                               MX6QDL_PAD_SD4_DAT5__UART2_RTS_B        0x1b0b0
-                               MX6QDL_PAD_SD4_DAT6__UART2_CTS_B        0x1b0b0
-                               MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b0
-                               MX6QDL_PAD_SD4_DAT3__GPIO2_IO11         0x130b0 /* BT_EN */
-                       >;
-               };
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b0
+                       MX6QDL_PAD_SD4_DAT5__UART2_RTS_B        0x1b0b0
+                       MX6QDL_PAD_SD4_DAT6__UART2_CTS_B        0x1b0b0
+                       MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b0
+                       MX6QDL_PAD_SD4_DAT3__GPIO2_IO11         0x130b0 /* BT_EN */
+               >;
+       };
 
-               pinctrl_usdhc1: usdhc1grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_SD1_CMD__SD1_CMD     0x17059
-                               MX6QDL_PAD_SD1_CLK__SD1_CLK     0x10059
-                               MX6QDL_PAD_SD1_DAT0__SD1_DATA0  0x17059
-                               MX6QDL_PAD_SD1_DAT1__SD1_DATA1  0x17059
-                               MX6QDL_PAD_SD1_DAT2__SD1_DATA2  0x17059
-                               MX6QDL_PAD_SD1_DAT3__SD1_DATA3  0x17059
-                               MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x1b0b0 /* WL_EN */
-                               MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x1b0b0 /* WL_IRQ */
-                       >;
-               };
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_CMD__SD1_CMD     0x17059
+                       MX6QDL_PAD_SD1_CLK__SD1_CLK     0x10059
+                       MX6QDL_PAD_SD1_DAT0__SD1_DATA0  0x17059
+                       MX6QDL_PAD_SD1_DAT1__SD1_DATA1  0x17059
+                       MX6QDL_PAD_SD1_DAT2__SD1_DATA2  0x17059
+                       MX6QDL_PAD_SD1_DAT3__SD1_DATA3  0x17059
+                       MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x130b0 /* WL_EN */
+                       MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x130b0 /* WL_IRQ */
+               >;
+       };
 
-               pinctrl_usdhc3: usdhc3grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_SD3_CMD__SD3_CMD     0x17059
-                               MX6QDL_PAD_SD3_CLK__SD3_CLK     0x10059
-                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0  0x17059
-                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1  0x17059
-                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2  0x17059
-                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3  0x17059
-                               MX6QDL_PAD_SD3_DAT4__SD3_DATA4  0x17059
-                               MX6QDL_PAD_SD3_DAT5__SD3_DATA5  0x17059
-                               MX6QDL_PAD_SD3_DAT6__SD3_DATA6  0x17059
-                               MX6QDL_PAD_SD3_DAT7__SD3_DATA7  0x17059
-                       >;
-               };
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD     0x17059
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK     0x10059
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0  0x17059
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1  0x17059
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2  0x17059
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3  0x17059
+                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4  0x17059
+                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5  0x17059
+                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6  0x17059
+                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7  0x17059
+               >;
        };
 };
index 9fc1fa4..b8e74ab 100644 (file)
@@ -1,49 +1,6 @@
-/*
- * Copyright 2015 Armadeus Systems
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this file; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Copyright 2015 Armadeus Systems <support@armadeus.com>
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
                stdout-path = &uart4;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm3 0 191000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <0>;
+               power-supply = <&reg_5v>;
+       };
+
        disp0 {
                compatible = "fsl,imx-parallel-display";
-               interface-pix-fmt = "bgr666";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu1_disp1>;
-
-               display-timings {
-                       lw700 {
-                               clock-frequency = <33000033>;
-                               hactive = <800>;
-                               vactive = <480>;
-                               hback-porch = <96>;
-                               hfront-porch = <96>;
-                               vback-porch = <20>;
-                               vfront-porch = <21>;
-                               hsync-len = <64>;
-                               vsync-len = <4>;
-                               hsync-active = <1>;
-                               vsync-active = <1>;
-                               de-active = <1>;
-                               pixelclk-active = <1>;
-                       };
-               };
+               pinctrl-0 = <&pinctrl_ipu1_disp0>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
 
-               port {
                        display_in: endpoint {
                                remote-endpoint = <&ipu1_di0_disp0>;
                        };
                };
+
+               port@1 {
+                       reg = <1>;
+
+                       display_out: endpoint {
+                               remote-endpoint = <&panel_in>;
+                       };
+               };
        };
 
        gpio-keys {
                };
        };
 
+       panel {
+               compatible = "armadeus,st0700-adapt";
+               power-supply = <&reg_3p3v>;
+               backlight = <&backlight>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&display_out>;
+                       };
+               };
+       };
+
        reg_3p3v: regulator-3p3v {
                compatible = "regulator-fixed";
                regulator-name = "3P3V";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-always-on;
+               vin-supply = <&reg_5v>;
        };
 
-       reg_usbh1_vbus: regulator-usb-h1-vbus {
+       reg_5v: regulator-5v {
                compatible = "regulator-fixed";
-               regulator-name = "usb_h1_vbus";
+               regulator-name = "5V";
                regulator-min-microvolt = <5000000>;
                regulator-max-microvolt = <5000000>;
                regulator-always-on;
 &can2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_flexcan2>;
+       xceiver-supply = <&reg_5v>;
        status = "okay";
 };
 
                VDDA-supply = <&reg_3p3v>;
                VDDIO-supply = <&reg_3p3v>;
        };
+
+       rtc@6f {
+               compatible = "microchip,mcp7940x";
+               reg = <0x6f>;
+       };
 };
 
 &i2c3 {
 };
 
 &usbh1 {
-       vbus-supply = <&reg_usbh1_vbus>;
+       vbus-supply = <&reg_5v>;
        phy_type = "utmi";
        status = "okay";
 };
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpios>;
 
-       apf6dev {
-               pinctrl_audmux: audmuxgrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_CSI0_DAT4__AUD3_TXC  0x1b0b0
-                               MX6QDL_PAD_CSI0_DAT5__AUD3_TXD  0x1b0b0
-                               MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x1b0b0
-                               MX6QDL_PAD_CSI0_DAT7__AUD3_RXD  0x1b0b0
-                               MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x130b0
-                       >;
-               };
+       pinctrl_audmux: audmuxgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT4__AUD3_TXC  0x1b0b0
+                       MX6QDL_PAD_CSI0_DAT5__AUD3_TXD  0x1b0b0
+                       MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x1b0b0
+                       MX6QDL_PAD_CSI0_DAT7__AUD3_RXD  0x1b0b0
+                       MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x130b0
+               >;
+       };
 
-               pinctrl_ecspi1: ecspi1grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
-                               MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
-                               MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
-                               MX6QDL_PAD_KEY_ROW1__GPIO4_IO09  0x1b0b0
-                               MX6QDL_PAD_KEY_ROW2__GPIO4_IO11  0x1b0b0
-                               MX6QDL_PAD_KEY_COL2__GPIO4_IO10  0x1b0b0
-                       >;
-               };
+       pinctrl_ecspi1: ecspi1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
+                       MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
+                       MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
+                       MX6QDL_PAD_KEY_ROW1__GPIO4_IO09  0x1b0b0
+                       MX6QDL_PAD_KEY_ROW2__GPIO4_IO11  0x1b0b0
+                       MX6QDL_PAD_KEY_COL2__GPIO4_IO10  0x1b0b0
+               >;
+       };
 
-               pinctrl_flexcan2: flexcan2grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0
-                               MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0
-                       >;
-               };
+       pinctrl_flexcan2: flexcan2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0
+                       MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0
+               >;
+       };
 
-               pinctrl_gpio_keys: gpiokeysgrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0
-                       >;
-               };
+       pinctrl_gpio_keys: gpiokeysgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0
+               >;
+       };
 
-               pinctrl_gpio_leds: gpioledsgrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x130b0
-                       >;
-               };
+       pinctrl_gpio_leds: gpioledsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x130b0
+               >;
+       };
 
-               pinctrl_gpios: gpiosgrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_DI0_PIN4__GPIO4_IO20         0x100b1
-                               MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12      0x100b1
-                               MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13      0x100b1
-                               MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14      0x100b1
-                               MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15      0x100b1
-                               MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16      0x100b1
-                               MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17      0x100b1
-                               MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18      0x100b1
-                               MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21       0x100b1
-                       >;
-               };
+       pinctrl_gpios: gpiosgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_DI0_PIN4__GPIO4_IO20         0x100b1
+                       MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12      0x100b1
+                       MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13      0x100b1
+                       MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14      0x100b1
+                       MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15      0x100b1
+                       MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16      0x100b1
+                       MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17      0x100b1
+                       MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18      0x100b1
+                       MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21       0x100b1
+               >;
+       };
 
-               pinctrl_gsm: gsmgrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_GPIO_4__GPIO1_IO04  0x130b0 /* GSM_POKIN */
-                               MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x130b0 /* GSM_PWR_EN */
-                       >;
-               };
+       pinctrl_gsm: gsmgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_4__GPIO1_IO04  0x130b0 /* GSM_POKIN */
+                       MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x130b0 /* GSM_PWR_EN */
+               >;
+       };
 
-               pinctrl_i2c1: i2c1grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
-                               MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
-                       >;
-               };
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+                       MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+               >;
+       };
 
-               pinctrl_i2c2: i2c2grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
-                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
-                       >;
-               };
+       pinctrl_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_6__I2C3_SDA 0x4001b8b1
-                               MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
-                       >;
-               };
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+                       MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+               >;
+       };
 
-               pinctrl_ipu1_disp1: ipu1disp1grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK      0x100b1
-                               MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15            0x100b1
-                               MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02             0x100b1
-                               MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03             0x100b1
-                               MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00        0x100b1
-                               MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01        0x100b1
-                               MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02        0x100b1
-                               MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03        0x100b1
-                               MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04        0x100b1
-                               MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05        0x100b1
-                               MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06        0x100b1
-                               MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07        0x100b1
-                               MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08        0x100b1
-                               MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09        0x100b1
-                               MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10       0x100b1
-                               MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11       0x100b1
-                               MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12       0x100b1
-                               MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13       0x100b1
-                               MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14       0x100b1
-                               MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15       0x100b1
-                               MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16       0x100b1
-                               MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17       0x100b1
-                       >;
-               };
+       pinctrl_ipu1_disp0: ipu1disp0grp {
+               fsl,pins = <
+                       MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK      0x100b1
+                       MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15            0x100b1
+                       MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02             0x100b1
+                       MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03             0x100b1
+                       MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00        0x100b1
+                       MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01        0x100b1
+                       MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02        0x100b1
+                       MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03        0x100b1
+                       MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04        0x100b1
+                       MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05        0x100b1
+                       MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06        0x100b1
+                       MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07        0x100b1
+                       MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08        0x100b1
+                       MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09        0x100b1
+                       MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10       0x100b1
+                       MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11       0x100b1
+                       MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12       0x100b1
+                       MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13       0x100b1
+                       MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14       0x100b1
+                       MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15       0x100b1
+                       MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16       0x100b1
+                       MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17       0x100b1
+               >;
+       };
 
-               pinctrl_pcie: pciegrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02 0x130b0
-                       >;
-               };
+       pinctrl_pcie: pciegrp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02 0x130b0
+               >;
+       };
 
-               pinctrl_pwm3: pwm3grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
-                       >;
-               };
+       pinctrl_pwm3: pwm3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+               >;
+       };
 
-               pinctrl_uart1: uart1grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b0
-                               MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b0
-                       >;
-               };
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b0
+                       MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b0
+               >;
+       };
 
-               pinctrl_uart3: uart3grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_EIM_D23__UART3_CTS_B   0x1b0b0
-                               MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b0
-                               MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b0
-                               MX6QDL_PAD_EIM_D31__UART3_RTS_B   0x1b0b0
-                       >;
-               };
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D23__UART3_CTS_B   0x1b0b0
+                       MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b0
+                       MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b0
+                       MX6QDL_PAD_EIM_D31__UART3_RTS_B   0x1b0b0
+               >;
+       };
 
-               pinctrl_uart4: uart4grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b0
-                               MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b0
-                       >;
-               };
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b0
+                       MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b0
+               >;
+       };
 
-               pinctrl_usbotg: usbotggrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x1b0b0
-                       >;
-               };
+       pinctrl_usbotg: usbotggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x1b0b0
+               >;
+       };
 
-               pinctrl_usdhc2: usdhc2grp {
-                       fsl,pins = <
-                               MX6QDL_PAD_SD2_CMD__SD2_CMD    0x17059
-                               MX6QDL_PAD_SD2_CLK__SD2_CLK    0x10059
-                               MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
-                               MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
-                               MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
-                               MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
-                       >;
-               };
+       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_spdif: spdifgrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_GPIO_19__SPDIF_OUT 0x1b0b0
-                       >;
-               };
+       pinctrl_spdif: spdifgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_19__SPDIF_OUT 0x1b0b0
+               >;
+       };
 
-               pinctrl_touchscreen: touchscreengrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03 0x1b0b0
-                       >;
-               };
+       pinctrl_touchscreen: touchscreengrp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03 0x1b0b0
+               >;
        };
 };
index 019dda6..d03dff2 100644 (file)
  */
 &i2c2 {
        clock-frequency = <100000>;
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c2>;
+       pinctrl-0 = <&pinctrl_i2c2_gpio>;
+       scl-gpios = <&gpio2 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio3 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        status = "okay";
 
        pmic: pfuze100@8 {
  */
 &i2c3 {
        clock-frequency = <100000>;
-       pinctrl-names = "default", "recovery";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c3>;
-       pinctrl-1 = <&pinctrl_i2c3_recovery>;
+       pinctrl-1 = <&pinctrl_i2c3_gpio>;
        scl-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        status = "disabled";
 };
 
 &iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbh_oc_1>;
+
        pinctrl_audmux: audmuxgrp {
                fsl,pins = <
                        MX6QDL_PAD_KEY_COL0__AUD5_TXC   0x130b0
                >;
        };
 
+       pinctrl_i2c2_gpio: i2c2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x4001b8b1
+                       MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x4001b8b1
+               >;
+       };
+
        pinctrl_i2c3: i2c3grp {
                fsl,pins = <
                        MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
                >;
        };
 
-       pinctrl_i2c3_recovery: i2c3recoverygrp {
+       pinctrl_i2c3_gpio: i2c3gpiogrp {
                fsl,pins = <
                        MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x4001b8b1
                        MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x4001b8b1
                >;
        };
 
+       pinctrl_usbh_oc_1: usbhoc1grp {
+               fsl,pins = <
+                       /* USBH_OC */
+                       MX6QDL_PAD_EIM_D30__GPIO3_IO30          0x1b0b0
+               >;
+       };
+
        pinctrl_spdif: spdifgrp {
                fsl,pins = <
                        MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
                >;
        };
 
+       pinctrl_usbc_id_1: usbc_id-1 {
+               fsl,pins = <
+                       /* USBC_ID */
+                       MX6QDL_PAD_NANDF_D2__GPIO2_IO02         0x1b0b0
+               >;
+       };
+
        pinctrl_usdhc1: usdhc1grp {
                fsl,pins = <
                        MX6QDL_PAD_SD1_CMD__SD1_CMD     0x17071
index c23ba22..c38e86e 100644 (file)
        sound-digital {
                compatible = "simple-audio-card";
                simple-audio-card,name = "tda1997x-audio";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,bitclock-master = <&sound_codec>;
+               simple-audio-card,frame-master = <&sound_codec>;
 
-               simple-audio-card,dai-link@0 {
-                       format = "i2s";
-
-                       cpu {
-                               sound-dai = <&ssi2>;
-                       };
+               sound_cpu: simple-audio-card,cpu {
+                       sound-dai = <&ssi2>;
+               };
 
-                       codec {
-                               bitclock-master;
-                               frame-master;
-                               sound-dai = <&hdmi_receiver>;
-                       };
+               sound_codec: simple-audio-card,codec {
+                       sound-dai = <&hdmi_receiver>;
                };
        };
 };
index 97f1659..de514eb 100644 (file)
        pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
+       pca9535: gpio-expander@27 {
+               compatible = "nxp,pca9535";
+               reg = <0x27>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pca9535>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
        eeprom@57 {
                compatible = "atmel,24c02";
                reg = <0x57>;
                        >;
                };
 
+               pinctrl_pca9535: pca9535grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CS3__GPIO6_IO16        0x17059
+                  >;
+               };
+
                pinctrl_uart1: uart1grp {
                        fsl,pins = <
                                MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA    0x1b0b1
index 776bfc7..828dd20 100644 (file)
                        >;
                };
 
+               pinctrl_usbotg: usbotg {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+                               MX6QDL_PAD_EIM_D22__USB_OTG_PWR 0x17059
+                               MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x17059
+                       >;
+               };
+
                pinctrl_usdhc3: usdhc3grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
        status = "okay";
 };
 
+&usbotg {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       status = "okay";
+};
+
 &usdhc3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc3>;
index 2cfb411..c070893 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii-id";
+       phy-handle = <&ethphy>;
        phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
        status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy: ethernet-phy@1 {
+                       reg = <1>;
+               };
+       };
 };
 
 &mipi_csi {
index 93be00a..a2a4f33 100644 (file)
                compatible = "fsl,mma8451";
                reg = <0x1c>;
                interrupt-parent = <&gpio1>;
-               interrupt-names = "int1", "int2";
-               interrupts = <18 IRQ_TYPE_LEVEL_LOW>, <20 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-names = "INT2";
+               interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+               vdd-supply = <&reg_3p3v>;
+               vddio-supply = <&reg_3p3v>;
        };
 
        hpa2: amp@60 {
 &iomuxc {
        pinctrl_accel: accelgrp {
                fsl,pins = <
-                       MX6QDL_PAD_SD1_CMD__GPIO1_IO18          0x4001b000
                        MX6QDL_PAD_SD1_CLK__GPIO1_IO20          0x4001b000
                >;
        };
index 3a96b55..59c54e6 100644 (file)
                        anatop: anatop@20c8000 {
                                compatible = "fsl,imx6sl-anatop",
                                             "fsl,imx6q-anatop",
-                                            "syscon", "simple-bus";
+                                            "syscon", "simple-mfd";
                                reg = <0x020c8000 0x1000>;
                                interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
                                             <0 54 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/boot/dts/imx6sll-kobo-clarahd.dts b/arch/arm/boot/dts/imx6sll-kobo-clarahd.dts
new file mode 100644 (file)
index 0000000..7214d1c
--- /dev/null
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: (GPL-2.0)
+/*
+ * Device tree for the Kobo Clara HD ebook reader
+ *
+ * Name on mainboard is: 37NB-E60K00+4A4
+ * Serials start with: E60K02 (a number also seen in
+ * vendor kernel sources)
+ *
+ * This mainboard seems to be equipped with different SoCs.
+ * In the Kobo Clara HD ebook reader it is an i.MX6SLL
+ *
+ * Copyright 2019 Andreas Kemnade
+ * based on works
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx6sll.dtsi"
+#include "e60k02.dtsi"
+
+/ {
+       model = "Kobo Clara HD";
+       compatible = "kobo,clarahd", "fsl,imx6sll";
+};
+
+&clks {
+       assigned-clocks = <&clks IMX6SLL_CLK_PLL4_AUDIO_DIV>;
+       assigned-clock-rates = <393216000>;
+};
+
+&cpu0 {
+       arm-supply = <&dcdc3_reg>;
+       soc-supply = <&dcdc1_reg>;
+};
+
+&gpio_keys {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpio_keys>;
+};
+
+&i2c1 {
+       pinctrl-names = "default","sleep";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       pinctrl-1 = <&pinctrl_i2c1_sleep>;
+};
+
+&i2c2 {
+       pinctrl-names = "default","sleep";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       pinctrl-1 = <&pinctrl_i2c2_sleep>;
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       pinctrl_gpio_keys: gpio-keysgrp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD1_DATA1__GPIO5_IO08        0x17059 /* PWR_SW */
+                       MX6SLL_PAD_SD1_DATA4__GPIO5_IO12        0x17059 /* HALL_EN */
+               >;
+       };
+
+       pinctrl_hog: hoggrp {
+               fsl,pins = <
+                       MX6SLL_PAD_LCD_DATA00__GPIO2_IO20       0x79
+                       MX6SLL_PAD_LCD_DATA01__GPIO2_IO21       0x79
+                       MX6SLL_PAD_LCD_DATA02__GPIO2_IO22       0x79
+                       MX6SLL_PAD_LCD_DATA03__GPIO2_IO23       0x79
+                       MX6SLL_PAD_LCD_DATA04__GPIO2_IO24       0x79
+                       MX6SLL_PAD_LCD_DATA05__GPIO2_IO25       0x79
+                       MX6SLL_PAD_LCD_DATA06__GPIO2_IO26       0x79
+                       MX6SLL_PAD_LCD_DATA07__GPIO2_IO27       0x79
+                       MX6SLL_PAD_LCD_DATA08__GPIO2_IO28       0x79
+                       MX6SLL_PAD_LCD_DATA09__GPIO2_IO29       0x79
+                       MX6SLL_PAD_LCD_DATA10__GPIO2_IO30       0x79
+                       MX6SLL_PAD_LCD_DATA11__GPIO2_IO31       0x79
+                       MX6SLL_PAD_LCD_DATA12__GPIO3_IO00       0x79
+                       MX6SLL_PAD_LCD_DATA13__GPIO3_IO01       0x79
+                       MX6SLL_PAD_LCD_DATA14__GPIO3_IO02       0x79
+                       MX6SLL_PAD_LCD_DATA15__GPIO3_IO03       0x79
+                       MX6SLL_PAD_LCD_DATA16__GPIO3_IO04       0x79
+                       MX6SLL_PAD_LCD_DATA17__GPIO3_IO05       0x79
+                       MX6SLL_PAD_LCD_DATA18__GPIO3_IO06       0x79
+                       MX6SLL_PAD_LCD_DATA19__GPIO3_IO07       0x79
+                       MX6SLL_PAD_LCD_DATA20__GPIO3_IO08       0x79
+                       MX6SLL_PAD_LCD_DATA21__GPIO3_IO09       0x79
+                       MX6SLL_PAD_LCD_DATA22__GPIO3_IO10       0x79
+                       MX6SLL_PAD_LCD_DATA23__GPIO3_IO11       0x79
+                       MX6SLL_PAD_LCD_CLK__GPIO2_IO15          0x79
+                       MX6SLL_PAD_LCD_ENABLE__GPIO2_IO16       0x79
+                       MX6SLL_PAD_LCD_HSYNC__GPIO2_IO17        0x79
+                       MX6SLL_PAD_LCD_VSYNC__GPIO2_IO18        0x79
+                       MX6SLL_PAD_LCD_RESET__GPIO2_IO19        0x79
+                       MX6SLL_PAD_KEY_COL3__GPIO3_IO30         0x79
+                       MX6SLL_PAD_KEY_ROW7__GPIO4_IO07         0x79
+                       MX6SLL_PAD_ECSPI2_MOSI__GPIO4_IO13      0x79
+                       MX6SLL_PAD_KEY_COL5__GPIO4_IO02         0x79
+                       MX6SLL_PAD_KEY_ROW6__GPIO4_IO05         0x79
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_I2C1_SCL__I2C1_SCL   0x4001f8b1
+                       MX6SLL_PAD_I2C1_SDA__I2C1_SDA   0x4001f8b1
+               >;
+       };
+
+       pinctrl_i2c1_sleep: i2c1grp-sleep {
+               fsl,pins = <
+                       MX6SLL_PAD_I2C1_SCL__I2C1_SCL   0x400108b1
+                       MX6SLL_PAD_I2C1_SDA__I2C1_SDA   0x400108b1
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6SLL_PAD_I2C2_SCL__I2C2_SCL   0x4001f8b1
+                       MX6SLL_PAD_I2C2_SDA__I2C2_SDA   0x4001f8b1
+               >;
+       };
+
+       pinctrl_i2c2_sleep: i2c2grp-sleep {
+               fsl,pins = <
+                       MX6SLL_PAD_I2C2_SCL__I2C2_SCL   0x400108b1
+                       MX6SLL_PAD_I2C2_SDA__I2C2_SDA   0x400108b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6SLL_PAD_REF_CLK_24M__I2C3_SCL 0x4001f8b1
+                       MX6SLL_PAD_REF_CLK_32K__I2C3_SDA 0x4001f8b1
+               >;
+       };
+
+       pinctrl_led: ledgrp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD1_DATA6__GPIO5_IO07 0x17059
+               >;
+       };
+
+       pinctrl_lm3630a_bl_gpio: lm3630a-bl-gpiogrp {
+               fsl,pins = <
+                       MX6SLL_PAD_EPDC_PWR_CTRL3__GPIO2_IO10   0x10059 /* HWEN */
+               >;
+       };
+
+       pinctrl_ricoh_gpio: ricoh-gpiogrp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD1_CLK__GPIO5_IO15  0x1b8b1 /* ricoh619 chg */
+                       MX6SLL_PAD_SD1_DATA0__GPIO5_IO11 0x1b8b1 /* ricoh619 irq */
+                       MX6SLL_PAD_KEY_COL2__GPIO3_IO28 0x1b8b1 /* ricoh619 bat_low_int */
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x1b0b1
+                       MX6SLL_PAD_UART1_RXD__UART1_DCE_RX 0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg1: usbotg1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID 0x17059
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD2_CMD__SD2_CMD             0x17059
+                       MX6SLL_PAD_SD2_CLK__SD2_CLK             0x13059
+                       MX6SLL_PAD_SD2_DATA0__SD2_DATA0         0x17059
+                       MX6SLL_PAD_SD2_DATA1__SD2_DATA1         0x17059
+                       MX6SLL_PAD_SD2_DATA2__SD2_DATA2         0x17059
+                       MX6SLL_PAD_SD2_DATA3__SD2_DATA3         0x17059
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp-100mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD2_CMD__SD2_CMD             0x170b9
+                       MX6SLL_PAD_SD2_CLK__SD2_CLK             0x130b9
+                       MX6SLL_PAD_SD2_DATA0__SD2_DATA0         0x170b9
+                       MX6SLL_PAD_SD2_DATA1__SD2_DATA1         0x170b9
+                       MX6SLL_PAD_SD2_DATA2__SD2_DATA2         0x170b9
+                       MX6SLL_PAD_SD2_DATA3__SD2_DATA3         0x170b9
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp-200mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD2_CMD__SD2_CMD             0x170f9
+                       MX6SLL_PAD_SD2_CLK__SD2_CLK             0x130f9
+                       MX6SLL_PAD_SD2_DATA0__SD2_DATA0         0x170f9
+                       MX6SLL_PAD_SD2_DATA1__SD2_DATA1         0x170f9
+                       MX6SLL_PAD_SD2_DATA2__SD2_DATA2         0x170f9
+                       MX6SLL_PAD_SD2_DATA3__SD2_DATA3         0x170f9
+               >;
+       };
+
+       pinctrl_usdhc2_sleep: usdhc2grp-sleep {
+               fsl,pins = <
+                       MX6SLL_PAD_SD2_CMD__GPIO5_IO04          0x100f9
+                       MX6SLL_PAD_SD2_CLK__GPIO5_IO05          0x100f9
+                       MX6SLL_PAD_SD2_DATA0__GPIO5_IO01        0x100f9
+                       MX6SLL_PAD_SD2_DATA1__GPIO4_IO30        0x100f9
+                       MX6SLL_PAD_SD2_DATA2__GPIO5_IO03        0x100f9
+                       MX6SLL_PAD_SD2_DATA3__GPIO4_IO28        0x100f9
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD3_CMD__SD3_CMD     0x11059
+                       MX6SLL_PAD_SD3_CLK__SD3_CLK     0x11059
+                       MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x11059
+                       MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x11059
+                       MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x11059
+                       MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x11059
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3grp-100mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD3_CMD__SD3_CMD     0x170b9
+                       MX6SLL_PAD_SD3_CLK__SD3_CLK     0x170b9
+                       MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x170b9
+                       MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x170b9
+                       MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x170b9
+                       MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x170b9
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3grp-200mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD3_CMD__SD3_CMD     0x170f9
+                       MX6SLL_PAD_SD3_CLK__SD3_CLK     0x170f9
+                       MX6SLL_PAD_SD3_DATA0__SD3_DATA0 0x170f9
+                       MX6SLL_PAD_SD3_DATA1__SD3_DATA1 0x170f9
+                       MX6SLL_PAD_SD3_DATA2__SD3_DATA2 0x170f9
+                       MX6SLL_PAD_SD3_DATA3__SD3_DATA3 0x170f9
+               >;
+       };
+
+       pinctrl_usdhc3_sleep: usdhc3grp-sleep {
+               fsl,pins = <
+                       MX6SLL_PAD_SD3_CMD__GPIO5_IO21  0x100c1
+                       MX6SLL_PAD_SD3_CLK__GPIO5_IO18  0x100c1
+                       MX6SLL_PAD_SD3_DATA0__GPIO5_IO19        0x100c1
+                       MX6SLL_PAD_SD3_DATA1__GPIO5_IO20        0x100c1
+                       MX6SLL_PAD_SD3_DATA2__GPIO5_IO16        0x100c1
+                       MX6SLL_PAD_SD3_DATA3__GPIO5_IO17        0x100c1
+               >;
+       };
+
+       pinctrl_wifi_power: wifi-powergrp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD2_DATA6__GPIO4_IO29        0x10059         /* WIFI_3V3_ON */
+               >;
+       };
+
+       pinctrl_wifi_reset: wifi-resetgrp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD2_DATA7__GPIO5_IO00        0x10059         /* WIFI_RST */
+               >;
+       };
+};
+
+&leds {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_led>;
+};
+
+&lm3630a {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lm3630a_bl_gpio>;
+};
+
+&reg_wifi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wifi_power>;
+};
+
+&ricoh619 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ricoh_gpio>;
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+};
+
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz","sleep";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+       pinctrl-3 = <&pinctrl_usdhc2_sleep>;
+};
+
+&usdhc3 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz","sleep";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       pinctrl-3 = <&pinctrl_usdhc3_sleep>;
+};
+
+&wifi_pwrseq {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wifi_reset>;
+};
index 13c7ba7..85aa8bb 100644 (file)
                        anatop: anatop@20c8000 {
                                compatible = "fsl,imx6sll-anatop",
                                             "fsl,imx6q-anatop",
-                                            "syscon", "simple-bus";
+                                            "syscon", "simple-mfd";
                                reg = <0x020c8000 0x4000>;
                                interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
index 531a52c..59bad60 100644 (file)
 
                        anatop: anatop@20c8000 {
                                compatible = "fsl,imx6sx-anatop", "fsl,imx6q-anatop",
-                                            "syscon", "simple-bus";
+                                            "syscon", "simple-mfd";
                                reg = <0x020c8000 0x1000>;
                                interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
index c2a9dd5..2121445 100644 (file)
                enable-active-high;
        };
 
+       reg_peri_3v3: regulator-peri-3v3 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_peri_3v3>;
+               regulator-name = "VPERI_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio5 2 GPIO_ACTIVE_LOW>;
+               /*
+                * If you want to want to make this dynamic please
+                * check schematics and test all affected peripherals:
+                *
+                * - sensors
+                * - ethernet phy
+                * - can
+                * - bluetooth
+                * - wm8960 audio codec
+                * - ov5640 camera
+                */
+               regulator-always-on;
+       };
+
        reg_can_3v3: regulator-can-3v3 {
                compatible = "regulator-fixed";
                regulator-name = "can-3v3";
        pinctrl-0 = <&pinctrl_enet1>;
        phy-mode = "rmii";
        phy-handle = <&ethphy0>;
+       phy-supply = <&reg_peri_3v3>;
        status = "okay";
 };
 
        pinctrl-0 = <&pinctrl_enet2>;
        phy-mode = "rmii";
        phy-handle = <&ethphy1>;
+       phy-supply = <&reg_peri_3v3>;
        status = "okay";
 
        mdio {
        pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
-       mag3110@e {
+       magnetometer@e {
                compatible = "fsl,mag3110";
                reg = <0x0e>;
+               vdd-supply = <&reg_peri_3v3>;
+               vddio-supply = <&reg_peri_3v3>;
        };
 };
 
        flash0: n25q256a@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "micron,n25q256a";
+               compatible = "micron,n25q256a", "jedec,spi-nor";
                spi-max-frequency = <29000000>;
                spi-rx-bus-width = <4>;
                spi-tx-bus-width = <4>;
 
 &usbotg1 {
        dr_mode = "otg";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usb_otg1>;
        status = "okay";
 };
 
                >;
        };
 
+       pinctrl_peri_3v3: peri3v3grp {
+               fsl,pins = <
+                       MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02      0x1b0b0
+               >;
+       };
+
        pinctrl_pwm1: pwm1grp {
                fsl,pins = <
                        MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
                >;
        };
 
+       pinctrl_usb_otg1: usbotg1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID    0x17059
+               >;
+       };
+
        pinctrl_usdhc1: usdhc1grp {
                fsl,pins = <
                        MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x17059
diff --git a/arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi b/arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi
new file mode 100644 (file)
index 0000000..f2386dc
--- /dev/null
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+//
+// Copyright 2019 Armadeus Systems <support@armadeus.com>
+
+/ {
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0>; /* will be filled by U-Boot */
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       usdhc3_pwrseq: usdhc3-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1>;
+       phy-mode = "rmii";
+       phy-reset-duration = <1>;
+       phy-reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
+       phy-handle = <&ethphy1>;
+       phy-supply = <&reg_3v3>;
+       status = "okay";
+
+       mdio: mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy1: ethernet-phy@1 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <1>;
+                       interrupt-parent = <&gpio4>;
+                       interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
+                       status = "okay";
+               };
+       };
+};
+
+/* Bluetooth */
+&uart8 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart8>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+/* eMMC */
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       bus-width = <8>;
+       no-1-8-v;
+       non-removable;
+       status = "okay";
+};
+
+/* WiFi */
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       bus-width = <4>;
+       no-1-8-v;
+       non-removable;
+       mmc-pwrseq = <&usdhc3_pwrseq>;
+       status = "okay";
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       brcmf: wifi@1 {
+               compatible = "brcm,bcm4329-fmac";
+               reg = <1>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-names = "host-wake";
+       };
+};
+
+&iomuxc {
+       pinctrl_enet1: enet1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b0b0
+                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0b0
+                       MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x130b0
+                       MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x130b0
+                       MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x130b0
+                       MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x130b0
+                       MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
+                       /* INT# */
+                       MX6UL_PAD_NAND_DQS__GPIO4_IO16          0x1b0b0
+                       /* RST# */
+                       MX6UL_PAD_NAND_DATA00__GPIO4_IO02       0x130b0
+                       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031
+               >;
+       };
+
+       pinctrl_uart8: uart8grp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET2_TX_EN__UART8_DCE_RX     0x1b0b0
+                       MX6UL_PAD_ENET2_TX_DATA1__UART8_DCE_TX  0x1b0b0
+                       MX6UL_PAD_ENET2_RX_ER__UART8_DCE_RTS    0x1b0b0
+                       MX6UL_PAD_ENET2_TX_CLK__UART8_DCE_CTS   0x1b0b0
+                       /* BT_REG_ON */
+                       MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10       0x130b0
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x17059
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x10059
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x17059
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x17059
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x17059
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x17059
+                       MX6UL_PAD_NAND_READY_B__USDHC1_DATA4    0x17059
+                       MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5      0x17059
+                       MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6      0x17059
+                       MX6UL_PAD_NAND_CLE__USDHC1_DATA7        0x17059
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_DATA18__USDHC2_CMD        0x1b0b0
+                       MX6UL_PAD_LCD_DATA19__USDHC2_CLK        0x100b0
+                       MX6UL_PAD_LCD_DATA20__USDHC2_DATA0      0x1b0b0
+                       MX6UL_PAD_LCD_DATA21__USDHC2_DATA1      0x1b0b0
+                       MX6UL_PAD_LCD_DATA22__USDHC2_DATA2      0x1b0b0
+                       MX6UL_PAD_LCD_DATA23__USDHC2_DATA3      0x1b0b0
+                       /* WL_REG_ON */
+                       MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09    0x130b0
+                       /* WL_IRQ */
+                       MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08    0x1b0b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ul-imx6ull-opos6uldev.dtsi b/arch/arm/boot/dts/imx6ul-imx6ull-opos6uldev.dtsi
new file mode 100644 (file)
index 0000000..1896635
--- /dev/null
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+//
+// Copyright 2019 Armadeus Systems <support@armadeus.com>
+
+/ {
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm3 0 191000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               power-supply = <&reg_5v>;
+               status = "okay";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys>;
+
+               user-button {
+                       label = "User button";
+                       gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+                       linux,code = <BTN_MISC>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               user-led {
+                       label = "User";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_led>;
+                       gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       onewire {
+               compatible = "w1-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_w1>;
+               gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+       };
+
+       panel: panel {
+               compatible = "armadeus,st0700-adapt";
+               power-supply = <&reg_3v3>;
+               backlight = <&backlight>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&lcdif_out>;
+                       };
+               };
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       reg_usbotg1_vbus: regulator-usbotg1vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usbotg1vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usbotg1_vbus>;
+               gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_usbotg2_vbus: regulator-usbotg2vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usbotg2vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usbotg2_vbus>;
+               gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&adc1 {
+       vref-supply = <&reg_3v3>;
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       xceiver-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&can2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       xceiver-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&ecspi4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi4>;
+       cs-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>, <&gpio4 3 GPIO_ACTIVE_LOW>;
+       status = "okay";
+
+       spidev0: spi@0 {
+               compatible = "spidev";
+               reg = <0>;
+               spi-max-frequency = <5000000>;
+       };
+
+       spidev1: spi@1 {
+               compatible = "spidev";
+               reg = <1>;
+               spi-max-frequency = <5000000>;
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       clock-frequency = <400000>;
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       clock-frequency = <400000>;
+       status = "okay";
+};
+
+&lcdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lcdif>;
+       status = "okay";
+
+       port {
+               lcdif_out: endpoint {
+                       remote-endpoint = <&panel_in>;
+               };
+       };
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>;
+       status = "okay";
+};
+
+&snvs_pwrkey {
+       status = "disabled";
+};
+
+&tsc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_tsc>;
+       xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+       measure-delay-time = <0xffff>;
+       pre-charge-time = <0xffff>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1_id>;
+       vbus-supply = <&reg_usbotg1_vbus>;
+       dr_mode = "otg";
+       disable-over-current;
+       status = "okay";
+};
+
+&usbotg2 {
+       vbus-supply = <&reg_usbotg2_vbus>;
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpios>;
+
+       pinctrl_ecspi4: ecspi4grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_DATA04__ECSPI4_SCLK      0x1b0b0
+                       MX6UL_PAD_NAND_DATA05__ECSPI4_MOSI      0x1b0b0
+                       MX6UL_PAD_NAND_DATA06__ECSPI4_MISO      0x1b0b0
+                       MX6UL_PAD_NAND_DATA01__GPIO4_IO03       0x1b0b0
+                       MX6UL_PAD_NAND_DATA07__GPIO4_IO09       0x1b0b0
+               >;
+       };
+
+       pinctrl_flexcan1: flexcan1grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX      0x0b0b0
+                       MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX      0x0b0b0
+               >;
+       };
+
+       pinctrl_flexcan2: flexcan2grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX      0x0b0b0
+                       MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX      0x0b0b0
+               >;
+       };
+
+       pinctrl_gpios: gpiosgrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x0b0b0
+                       MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25     0x0b0b0
+                       MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24     0x0b0b0
+                       MX6UL_PAD_NAND_RE_B__GPIO4_IO00         0x0b0b0
+                       MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0x0b0b0
+                       MX6UL_PAD_UART1_CTS_B__GPIO1_IO18       0x0b0b0
+                       MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x0b0b0
+                       MX6UL_PAD_NAND_WE_B__GPIO4_IO01         0x0b0b0
+               >;
+       };
+
+       pinctrl_gpio_keys: gpiokeysgrp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11    0x0b0b0
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART4_RX_DATA__I2C1_SDA       0x4001b8b0
+                       MX6UL_PAD_UART4_TX_DATA__I2C1_SCL       0x4001b8b0
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART5_RX_DATA__I2C2_SDA       0x4001b8b0
+                       MX6UL_PAD_UART5_TX_DATA__I2C2_SCL       0x4001b8b0
+               >;
+       };
+
+       pinctrl_lcdif: lcdifgrp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x100b1
+                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x100b1
+                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x100b1
+                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x100b1
+                       MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x100b1
+                       MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x100b1
+                       MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x100b1
+                       MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x100b1
+                       MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x100b1
+                       MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x100b1
+                       MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x100b1
+                       MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x100b1
+                       MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x100b1
+                       MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x100b1
+                       MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x100b1
+                       MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x100b1
+                       MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x100b1
+                       MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x100b1
+                       MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x100b1
+                       MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x100b1
+                       MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x100b1
+                       MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x100b1
+               >;
+       };
+
+       pinctrl_led: ledgrp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_RESET__GPIO3_IO04         0x0b0b0
+               >;
+       };
+
+       pinctrl_pwm3: pwm3grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_ALE__PWM3_OUT            0x1b0b0
+               >;
+       };
+
+       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
+                       MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg1_id: usbotg1idgrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID    0x1b0b0
+               >;
+       };
+
+       pinctrl_usbotg1_vbus: usbotg1vbusgrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO05__GPIO1_IO05        0x1b0b0
+               >;
+       };
+};
index 0205fd5..5a3e06d 100644 (file)
 /dts-v1/;
 
 #include "imx6ul-kontron-n6310-som.dtsi"
+#include "imx6ul-kontron-n6x1x-s.dtsi"
 
 / {
        model = "Kontron N6310 S";
        compatible = "kontron,imx6ul-n6310-s", "kontron,imx6ul-n6310-som",
                     "fsl,imx6ul";
-
-       gpio-leds {
-               compatible = "gpio-leds";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_gpio_leds>;
-
-               led1 {
-                       label = "debug-led1";
-                       gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
-                       default-state = "off";
-                       linux,default-trigger = "heartbeat";
-               };
-
-               led2 {
-                       label = "debug-led2";
-                       gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
-                       default-state = "off";
-               };
-
-               led3 {
-                       label = "debug-led3";
-                       gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
-                       default-state = "off";
-               };
-       };
-
-       pwm-beeper {
-               compatible = "pwm-beeper";
-               pwms = <&pwm8 0 5000>;
-       };
-
-       reg_3v3: regulator-3v3 {
-               compatible = "regulator-fixed";
-               regulator-name = "3v3";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-       };
-
-       reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
-               compatible = "regulator-fixed";
-               regulator-name = "usb_otg1_vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-
-       reg_vref_adc: regulator-vref-adc {
-               compatible = "regulator-fixed";
-               regulator-name = "vref-adc";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-       };
-};
-
-&adc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_adc1>;
-       num-channels = <3>;
-       vref-supply = <&reg_vref_adc>;
-       status = "okay";
-};
-
-&can2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_flexcan2>;
-       status = "okay";
-};
-
-&ecspi1 {
-       cs-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1>;
-       status = "okay";
-
-       eeprom@0 {
-               compatible = "anvo,anv32e61w", "atmel,at25";
-               reg = <0>;
-               spi-max-frequency = <20000000>;
-               spi-cpha;
-               spi-cpol;
-               pagesize = <1>;
-               size = <8192>;
-               address-width = <16>;
-       };
-};
-
-&fec1 {
-       pinctrl-0 = <&pinctrl_enet1>;
-       /delete-node/ mdio;
-};
-
-&fec2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet2 &pinctrl_enet2_mdio>;
-       phy-mode = "rmii";
-       phy-handle = <&ethphy2>;
-       status = "okay";
-
-       mdio {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               ethphy1: ethernet-phy@1 {
-                       reg = <1>;
-                       micrel,led-mode = <0>;
-                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
-                       clock-names = "rmii-ref";
-               };
-
-               ethphy2: ethernet-phy@2 {
-                       reg = <2>;
-                       micrel,led-mode = <0>;
-                       clocks = <&clks IMX6UL_CLK_ENET2_REF>;
-                       clock-names = "rmii-ref";
-               };
-       };
-};
-
-&i2c1 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1>;
-       status = "okay";
-};
-
-&i2c4 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c4>;
-       status = "okay";
-
-       rtc@32 {
-               compatible = "epson,rx8900";
-               reg = <0x32>;
-       };
-};
-
-&pwm8 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pwm8>;
-       status = "okay";
-};
-
-&snvs_poweroff {
-       status = "okay";
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1>;
-       status = "okay";
-};
-
-&uart2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2>;
-       linux,rs485-enabled-at-boot-time;
-       rs485-rx-during-tx;
-       rs485-rts-active-low;
-       uart-has-rtscts;
-       status = "okay";
-};
-
-&uart3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3>;
-       fsl,uart-has-rtscts;
-       status = "okay";
-};
-
-&uart4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4>;
-       status = "okay";
-};
-
-&usbotg1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg1>;
-       dr_mode = "otg";
-       srp-disable;
-       hnp-disable;
-       adp-disable;
-       vbus-supply = <&reg_usb_otg1_vbus>;
-       status = "okay";
-};
-
-&usbotg2 {
-       dr_mode = "host";
-       disable-over-current;
-       status = "okay";
-};
-
-&usdhc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc1>;
-       cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
-       keep-power-in-suspend;
-       wakeup-source;
-       vmmc-supply = <&reg_3v3>;
-       voltage-ranges = <3300 3300>;
-       no-1-8-v;
-       status = "okay";
-};
-
-&usdhc2 {
-       pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc2>;
-       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
-       non-removable;
-       keep-power-in-suspend;
-       wakeup-source;
-       vmmc-supply = <&reg_3v3>;
-       voltage-ranges = <3300 3300>;
-       no-1-8-v;
-       status = "okay";
-};
-
-&wdog1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_wdog>;
-       fsl,ext-reset-output;
-       status = "okay";
-};
-
-&iomuxc {
-       pinctrl-0 = <&pinctrl_reset_out &pinctrl_gpio>;
-
-       pinctrl_adc1: adc1grp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO02__GPIO1_IO02        0xb0
-                       MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0xb0
-                       MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0xb0
-               >;
-       };
-
-       /* FRAM */
-       pinctrl_ecspi1: ecspi1grp {
-               fsl,pins = <
-                       MX6UL_PAD_CSI_DATA07__ECSPI1_MISO       0x100b1
-                       MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI       0x100b1
-                       MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK       0x100b1
-                       MX6UL_PAD_CSI_DATA05__GPIO4_IO26        0x100b1 /* ECSPI1-CS1 */
-               >;
-       };
-
-       pinctrl_enet2: enet2grp {
-               fsl,pins = <
-                       MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN      0x1b0b0
-                       MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER      0x1b0b0
-                       MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
-                       MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
-                       MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b0b0
-                       MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
-                       MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
-                       MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b009
-               >;
-       };
-
-       pinctrl_enet2_mdio: enet2mdiogrp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO07__ENET2_MDC         0x1b0b0
-                       MX6UL_PAD_GPIO1_IO06__ENET2_MDIO        0x1b0b0
-               >;
-       };
-
-       pinctrl_flexcan2: flexcan2grp{
-               fsl,pins = <
-                       MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX      0x1b020
-                       MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX      0x1b020
-               >;
-       };
-
-       pinctrl_gpio: gpiogrp {
-               fsl,pins = <
-                       MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05      0x1b0b0 /* DOUT1 */
-                       MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04      0x1b0b0 /* DIN1 */
-                       MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01      0x1b0b0 /* DOUT2 */
-                       MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x1b0b0 /* DIN2 */
-               >;
-       };
-
-       pinctrl_gpio_leds: gpioledsgrp {
-               fsl,pins = <
-                       MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30     0x1b0b0 /* LED H14 */
-                       MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x1b0b0 /* LED H15 */
-                       MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02      0x1b0b0 /* LED H16 */
-               >;
-       };
-
-       pinctrl_i2c1: i2c1grp {
-               fsl,pins = <
-                       MX6UL_PAD_CSI_PIXCLK__I2C1_SCL          0x4001b8b0
-                       MX6UL_PAD_CSI_MCLK__I2C1_SDA            0x4001b8b0
-               >;
-       };
-
-       pinctrl_i2c4: i2c4grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART2_TX_DATA__I2C4_SCL       0x4001f8b0
-                       MX6UL_PAD_UART2_RX_DATA__I2C4_SDA       0x4001f8b0
-               >;
-       };
-
-       pinctrl_pwm8: pwm8grp {
-               fsl,pins = <
-                       MX6UL_PAD_CSI_HSYNC__PWM8_OUT           0x110b0
-               >;
-       };
-
-       pinctrl_uart1: uart1grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX   0x1b0b1
-                       MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX   0x1b0b1
-               >;
-       };
-
-       pinctrl_uart2: uart2grp {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_DATA04__UART2_DCE_TX     0x1b0b1
-                       MX6UL_PAD_NAND_DATA05__UART2_DCE_RX     0x1b0b1
-                       MX6UL_PAD_NAND_DATA06__UART2_DCE_CTS    0x1b0b1
-                       /*
-                        * mux unused RTS to make sure it doesn't cause
-                        * any interrupts when it is undefined
-                        */
-                       MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS    0x1b0b1
-               >;
-       };
-
-       pinctrl_uart3: uart3grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX   0x1b0b1
-                       MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX   0x1b0b1
-                       MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS    0x1b0b1
-                       MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS    0x1b0b1
-               >;
-       };
-
-       pinctrl_uart4: uart4grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX   0x1b0b1
-                       MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX   0x1b0b1
-               >;
-       };
-
-       pinctrl_usbotg1: usbotg1 {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO04__GPIO1_IO04        0x1b0b0
-               >;
-       };
-
-       pinctrl_usdhc1: usdhc1grp {
-               fsl,pins = <
-                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x17059
-                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x10059
-                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x17059
-                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x17059
-                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x17059
-                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x17059
-                       MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x100b1 /* SD1_CD */
-               >;
-       };
-
-       pinctrl_usdhc2: usdhc2grp {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x10059
-                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x17059
-                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x17059
-                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x17059
-                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x17059
-                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x17059
-               >;
-       };
-
-       pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100b9
-                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170b9
-                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170b9
-                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170b9
-                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170b9
-                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170b9
-               >;
-       };
-
-       pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100f9
-                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170f9
-                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170f9
-                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170f9
-                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170f9
-                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170f9
-               >;
-       };
-
-       pinctrl_wdog: wdoggrp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY    0x30b0
-               >;
-       };
 };
index a896b23..47d3ce5 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include "imx6ul.dtsi"
-#include <dt-bindings/gpio/gpio.h>
+#include "imx6ul-kontron-n6x1x-som-common.dtsi"
 
 / {
        model = "Kontron N6310 SOM";
        };
 };
 
-&ecspi2 {
-       cs-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi2>;
-       status = "okay";
-
-       spi-flash@0 {
-               compatible = "mxicy,mx25v8035f", "jedec,spi-nor";
-               spi-max-frequency = <50000000>;
-               reg = <0>;
-       };
-};
-
-&fec1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet1_mdio>;
-       phy-mode = "rmii";
-       phy-handle = <&ethphy1>;
-       status = "okay";
-
-       mdio {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               ethphy1: ethernet-phy@1 {
-                       reg = <1>;
-                       micrel,led-mode = <0>;
-                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
-                       clock-names = "rmii-ref";
-               };
-       };
-};
-
-&fec2 {
-       phy-mode = "rmii";
-       status = "disabled";
-};
-
 &qspi {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_qspi>;
-       status = "okay";
-
        spi-flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
                };
        };
 };
-
-&iomuxc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_reset_out>;
-
-       pinctrl_ecspi2: ecspi2grp {
-               fsl,pins = <
-                       MX6UL_PAD_CSI_DATA03__ECSPI2_MISO      0x100b1
-                       MX6UL_PAD_CSI_DATA02__ECSPI2_MOSI      0x100b1
-                       MX6UL_PAD_CSI_DATA00__ECSPI2_SCLK      0x100b1
-                       MX6UL_PAD_CSI_DATA01__GPIO4_IO22       0x100b1
-               >;
-       };
-
-       pinctrl_enet1: enet1grp {
-               fsl,pins = <
-                       MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x1b0b0
-                       MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x1b0b0
-                       MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
-                       MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
-                       MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
-                       MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
-                       MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
-                       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b009
-               >;
-       };
-
-       pinctrl_enet1_mdio: enet1mdiogrp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0b0
-                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b0b0
-               >;
-       };
-
-       pinctrl_qspi: qspigrp {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK        0x70a1
-                       MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00   0x70a1
-                       MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01     0x70a1
-                       MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02     0x70a1
-                       MX6UL_PAD_NAND_CLE__QSPI_A_DATA03       0x70a1
-                       MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B        0x70a1
-               >;
-       };
-
-       pinctrl_reset_out: rstoutgrp {
-               fsl,pins = <
-                       MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09      0x1b0b0
-               >;
-       };
-};
diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6311-s.dts b/arch/arm/boot/dts/imx6ul-kontron-n6311-s.dts
new file mode 100644 (file)
index 0000000..239a1af
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ */
+
+/dts-v1/;
+
+#include "imx6ul-kontron-n6311-som.dtsi"
+#include "imx6ul-kontron-n6x1x-s.dtsi"
+
+/ {
+       model = "Kontron N6311 S";
+       compatible = "kontron,imx6ul-n6311-s", "kontron,imx6ul-n6311-som",
+                    "fsl,imx6ul";
+};
diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi
new file mode 100644 (file)
index 0000000..a095a76
--- /dev/null
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ */
+
+#include "imx6ul.dtsi"
+#include "imx6ul-kontron-n6x1x-som-common.dtsi"
+
+/ {
+       model = "Kontron N6311 SOM";
+       compatible = "kontron,imx6ul-n6311-som", "fsl,imx6ul";
+
+       memory@80000000 {
+               reg = <0x80000000 0x20000000>;
+               device_type = "memory";
+       };
+};
+
+&qspi {
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-nand";
+               spi-max-frequency = <104000000>;
+               spi-tx-bus-width = <4>;
+               spi-rx-bus-width = <4>;
+               reg = <0>;
+
+               partition@0 {
+                       label = "ubi1";
+                       reg = <0x00000000 0x08000000>;
+               };
+
+               partition@8000000 {
+                       label = "ubi2";
+                       reg = <0x08000000 0x18000000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-s.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-s.dtsi
new file mode 100644 (file)
index 0000000..f05e918
--- /dev/null
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ * Copyright (c) 2019 Krzysztof Kozlowski <krzk@kernel.org>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led1 {
+                       label = "debug-led1";
+                       gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led2 {
+                       label = "debug-led2";
+                       gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led3 {
+                       label = "debug-led3";
+                       gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+       };
+
+       pwm-beeper {
+               compatible = "pwm-beeper";
+               pwms = <&pwm8 0 5000>;
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg1_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_vref_adc: regulator-vref-adc {
+               compatible = "regulator-fixed";
+               regulator-name = "vref-adc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&adc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc1>;
+       num-channels = <3>;
+       vref-supply = <&reg_vref_adc>;
+       status = "okay";
+};
+
+&can2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       status = "okay";
+};
+
+&ecspi1 {
+       cs-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       status = "okay";
+
+       eeprom@0 {
+               compatible = "anvo,anv32e61w", "atmel,at25";
+               reg = <0>;
+               spi-max-frequency = <20000000>;
+               spi-cpha;
+               spi-cpol;
+               pagesize = <1>;
+               size = <8192>;
+               address-width = <16>;
+       };
+};
+
+&fec1 {
+       pinctrl-0 = <&pinctrl_enet1>;
+       /delete-node/ mdio;
+};
+
+&fec2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet2 &pinctrl_enet2_mdio>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy2>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy1: ethernet-phy@1 {
+                       reg = <1>;
+                       micrel,led-mode = <0>;
+                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
+                       clock-names = "rmii-ref";
+               };
+
+               ethphy2: ethernet-phy@2 {
+                       reg = <2>;
+                       micrel,led-mode = <0>;
+                       clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+                       clock-names = "rmii-ref";
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+};
+
+&i2c4 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c4>;
+       status = "okay";
+
+       rtc@32 {
+               compatible = "epson,rx8900";
+               reg = <0x32>;
+       };
+};
+
+&pwm8 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm8>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       linux,rs485-enabled-at-boot-time;
+       rs485-rx-during-tx;
+       rs485-rts-active-low;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1>;
+       dr_mode = "otg";
+       srp-disable;
+       hnp-disable;
+       adp-disable;
+       over-current-active-low;
+       vbus-supply = <&reg_usb_otg1_vbus>;
+       status = "okay";
+};
+
+&usbotg2 {
+       dr_mode = "host";
+       disable-over-current;
+       vbus-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+       keep-power-in-suspend;
+       wakeup-source;
+       vmmc-supply = <&reg_3v3>;
+       voltage-ranges = <3300 3300>;
+       no-1-8-v;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+       non-removable;
+       keep-power-in-suspend;
+       wakeup-source;
+       vmmc-supply = <&reg_3v3>;
+       voltage-ranges = <3300 3300>;
+       no-1-8-v;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-0 = <&pinctrl_reset_out &pinctrl_gpio>;
+
+       pinctrl_adc1: adc1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO02__GPIO1_IO02        0xb0
+                       MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0xb0
+                       MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0xb0
+               >;
+       };
+
+       pinctrl_ecspi1: ecspi1grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_DATA07__ECSPI1_MISO       0x100b1
+                       MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI       0x100b1
+                       MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK       0x100b1
+                       MX6UL_PAD_CSI_DATA05__GPIO4_IO26        0x100b1 /* ECSPI1-CS1 */
+               >;
+       };
+
+       pinctrl_enet2: enet2grp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN      0x1b0b0
+                       MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER      0x1b0b0
+                       MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+                       MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b0b0
+                       MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b009
+               >;
+       };
+
+       pinctrl_enet2_mdio: enet2mdiogrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__ENET2_MDC         0x1b0b0
+                       MX6UL_PAD_GPIO1_IO06__ENET2_MDIO        0x1b0b0
+               >;
+       };
+
+       pinctrl_flexcan2: flexcan2grp{
+               fsl,pins = <
+                       MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX      0x1b020
+                       MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX      0x1b020
+               >;
+       };
+
+       pinctrl_gpio: gpiogrp {
+               fsl,pins = <
+                       MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05      0x1b0b0 /* DOUT1 */
+                       MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04      0x1b0b0 /* DIN1 */
+                       MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01      0x1b0b0 /* DOUT2 */
+                       MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x1b0b0 /* DIN2 */
+               >;
+       };
+
+       pinctrl_gpio_leds: gpioledsgrp {
+               fsl,pins = <
+                       MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30     0x1b0b0 /* LED H14 */
+                       MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x1b0b0 /* LED H15 */
+                       MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02      0x1b0b0 /* LED H16 */
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_PIXCLK__I2C1_SCL          0x4001b8b0
+                       MX6UL_PAD_CSI_MCLK__I2C1_SDA            0x4001b8b0
+               >;
+       };
+
+       pinctrl_i2c4: i2c4grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_TX_DATA__I2C4_SCL       0x4001f8b0
+                       MX6UL_PAD_UART2_RX_DATA__I2C4_SDA       0x4001f8b0
+               >;
+       };
+
+       pinctrl_pwm8: pwm8grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_HSYNC__PWM8_OUT           0x110b0
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_DATA04__UART2_DCE_TX     0x1b0b1
+                       MX6UL_PAD_NAND_DATA05__UART2_DCE_RX     0x1b0b1
+                       MX6UL_PAD_NAND_DATA06__UART2_DCE_CTS    0x1b0b1
+                       /*
+                        * mux unused RTS to make sure it doesn't cause
+                        * any interrupts when it is undefined
+                        */
+                       MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX   0x1b0b1
+                       MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS    0x1b0b1
+                       MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg1: usbotg1 {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO04__GPIO1_IO04        0x1b0b0
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x17059
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x10059
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x17059
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x17059
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x17059
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x17059
+                       MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x100b1 /* SD1_CD */
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x10059
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x17059
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x17059
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x17059
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x17059
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x17059
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100b9
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170b9
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170b9
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170b9
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170b9
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170b9
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100f9
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170f9
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170f9
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170f9
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170f9
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170f9
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY    0x30b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi
new file mode 100644 (file)
index 0000000..a17af4d
--- /dev/null
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ * Copyright (c) 2019 Krzysztof Kozlowski <krzk@kernel.org>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       chosen {
+               stdout-path = &uart4;
+       };
+};
+
+&ecspi2 {
+       cs-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi2>;
+       status = "okay";
+
+       spi-flash@0 {
+               compatible = "mxicy,mx25v8035f", "jedec,spi-nor";
+               spi-max-frequency = <50000000>;
+               reg = <0>;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet1_mdio>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy1>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy1: ethernet-phy@1 {
+                       reg = <1>;
+                       micrel,led-mode = <0>;
+                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
+                       clock-names = "rmii-ref";
+               };
+       };
+};
+
+&fec2 {
+       phy-mode = "rmii";
+       status = "disabled";
+};
+
+&qspi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_reset_out>;
+
+       pinctrl_ecspi2: ecspi2grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_DATA03__ECSPI2_MISO      0x100b1
+                       MX6UL_PAD_CSI_DATA02__ECSPI2_MOSI      0x100b1
+                       MX6UL_PAD_CSI_DATA00__ECSPI2_SCLK      0x100b1
+                       MX6UL_PAD_CSI_DATA01__GPIO4_IO22       0x100b1
+               >;
+       };
+
+       pinctrl_enet1: enet1grp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x1b0b0
+                       MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x1b0b0
+                       MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+                       MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
+                       MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b009
+               >;
+       };
+
+       pinctrl_enet1_mdio: enet1mdiogrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0b0
+                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b0b0
+               >;
+       };
+
+       pinctrl_qspi: qspigrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK        0x70a1
+                       MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00   0x70a1
+                       MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01     0x70a1
+                       MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02     0x70a1
+                       MX6UL_PAD_NAND_CLE__QSPI_A_DATA03       0x70a1
+                       MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B        0x70a1
+               >;
+       };
+
+       pinctrl_reset_out: rstoutgrp {
+               fsl,pins = <
+                       MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09      0x1b0b0
+               >;
+       };
+};
index cf7faf4..6ce84f9 100644 (file)
@@ -1,193 +1,6 @@
-/*
- * Copyright 2017 Armadeus Systems <support@armadeus.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this file; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+//
+// Copyright 2017 Armadeus Systems <support@armadeus.com>
 
 #include "imx6ul.dtsi"
-
-/ {
-       memory@80000000 {
-               device_type = "memory";
-               reg = <0x80000000 0>; /* will be filled by U-Boot */
-       };
-
-       reg_3v3: regulator-3v3 {
-               compatible = "regulator-fixed";
-               regulator-name = "3V3";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-       };
-
-       usdhc3_pwrseq: usdhc3-pwrseq {
-               compatible = "mmc-pwrseq-simple";
-               reset-gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
-       };
-};
-
-&fec1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet1>;
-       phy-mode = "rmii";
-       phy-reset-duration = <1>;
-       phy-reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
-       phy-handle = <&ethphy1>;
-       phy-supply = <&reg_3v3>;
-       status = "okay";
-
-       mdio: mdio {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               ethphy1: ethernet-phy@1 {
-                       compatible = "ethernet-phy-ieee802.3-c22";
-                       reg = <1>;
-                       interrupt-parent = <&gpio4>;
-                       interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
-                       status = "okay";
-               };
-       };
-};
-
-/* Bluetooth */
-&uart8 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart8>;
-       uart-has-rtscts;
-       status = "okay";
-};
-
-/* eMMC */
-&usdhc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc1>;
-       bus-width = <8>;
-       no-1-8-v;
-       non-removable;
-       status = "okay";
-};
-
-/* WiFi */
-&usdhc2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2>;
-       bus-width = <4>;
-       no-1-8-v;
-       non-removable;
-       mmc-pwrseq = <&usdhc3_pwrseq>;
-       status = "okay";
-
-       #address-cells = <1>;
-       #size-cells = <0>;
-
-       brcmf: wifi@1 {
-               compatible = "brcm,bcm4329-fmac";
-               reg = <1>;
-               interrupt-parent = <&gpio2>;
-               interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
-               interrupt-names = "host-wake";
-       };
-};
-
-&iomuxc {
-       pinctrl_enet1: enet1grp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b0b0
-                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0b0
-                       MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x130b0
-                       MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x130b0
-                       MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x130b0
-                       MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x130b0
-                       MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
-                       MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
-                       MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
-                       /* INT# */
-                       MX6UL_PAD_NAND_DQS__GPIO4_IO16          0x1b0b0
-                       /* RST# */
-                       MX6UL_PAD_NAND_DATA00__GPIO4_IO02       0x130b0
-                       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031
-               >;
-       };
-
-       pinctrl_uart8: uart8grp {
-               fsl,pins = <
-                       MX6UL_PAD_ENET2_TX_EN__UART8_DCE_RX     0x1b0b0
-                       MX6UL_PAD_ENET2_TX_DATA1__UART8_DCE_TX  0x1b0b0
-                       MX6UL_PAD_ENET2_RX_ER__UART8_DCE_RTS    0x1b0b0
-                       MX6UL_PAD_ENET2_TX_CLK__UART8_DCE_CTS   0x1b0b0
-                       /* BT_REG_ON */
-                       MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10       0x130b0
-               >;
-       };
-
-       pinctrl_usdhc1: usdhc1grp {
-               fsl,pins = <
-                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x17059
-                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x10059
-                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x17059
-                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x17059
-                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x17059
-                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x17059
-                       MX6UL_PAD_NAND_READY_B__USDHC1_DATA4    0x17059
-                       MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5      0x17059
-                       MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6      0x17059
-                       MX6UL_PAD_NAND_CLE__USDHC1_DATA7        0x17059
-               >;
-       };
-
-       pinctrl_usdhc2: usdhc2grp {
-               fsl,pins = <
-                       MX6UL_PAD_LCD_DATA18__USDHC2_CMD        0x1b0b0
-                       MX6UL_PAD_LCD_DATA19__USDHC2_CLK        0x100b0
-                       MX6UL_PAD_LCD_DATA20__USDHC2_DATA0      0x1b0b0
-                       MX6UL_PAD_LCD_DATA21__USDHC2_DATA1      0x1b0b0
-                       MX6UL_PAD_LCD_DATA22__USDHC2_DATA2      0x1b0b0
-                       MX6UL_PAD_LCD_DATA23__USDHC2_DATA3      0x1b0b0
-                       /* WL_REG_ON */
-                       MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09    0x130b0
-                       /* WL_IRQ */
-                       MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08    0x1b0b0
-               >;
-       };
-};
+#include "imx6ul-imx6ull-opos6ul.dtsi"
index 8ecdb9a..375b98d 100644 (file)
-/*
- * Copyright 2017 Armadeus Systems <support@armadeus.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this file; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+//
+// Copyright 2017 Armadeus Systems <support@armadeus.com>
 
 /dts-v1/;
 #include "imx6ul-opos6ul.dtsi"
+#include "imx6ul-imx6ull-opos6uldev.dtsi"
 
 / {
-       model = "Armadeus Systems OPOS6UL SoM on OPOS6ULDev board";
-       compatible = "armadeus,opos6uldev", "armadeus,opos6ul", "fsl,imx6ul";
-
-       chosen {
-               stdout-path = &uart1;
-       };
-
-       backlight: backlight {
-               compatible = "pwm-backlight";
-               pwms = <&pwm3 0 191000>;
-               brightness-levels = <0 4 8 16 32 64 128 255>;
-               default-brightness-level = <7>;
-               power-supply = <&reg_5v>;
-               status = "okay";
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_gpio_keys>;
-
-               user-button {
-                       label = "User button";
-                       gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
-                       linux,code = <BTN_MISC>;
-                       wakeup-source;
-               };
-       };
-
-       leds {
-               compatible = "gpio-leds";
-
-               user-led {
-                       label = "User";
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_led>;
-                       gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger = "heartbeat";
-               };
-       };
-
-       onewire {
-               compatible = "w1-gpio";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_w1>;
-               gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
-       };
-
-       panel: panel {
-               compatible = "armadeus,st0700-adapt";
-               power-supply = <&reg_3v3>;
-               backlight = <&backlight>;
-
-               port {
-                       panel_in: endpoint {
-                               remote-endpoint = <&lcdif_out>;
-                       };
-               };
-       };
-
-       reg_5v: regulator-5v {
-               compatible = "regulator-fixed";
-               regulator-name = "5V";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-       };
-
-       reg_usbotg1_vbus: regulator-usbotg1vbus {
-               compatible = "regulator-fixed";
-               regulator-name = "usbotg1vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_usbotg1_vbus>;
-               gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-
-       reg_usbotg2_vbus: regulator-usbotg2vbus {
-               compatible = "regulator-fixed";
-               regulator-name = "usbotg2vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_usbotg2_vbus>;
-               gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-};
-
-&adc1 {
-       vref-supply = <&reg_3v3>;
-       status = "okay";
-};
-
-&can1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_flexcan1>;
-       xceiver-supply = <&reg_5v>;
-       status = "okay";
-};
-
-&can2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_flexcan2>;
-       xceiver-supply = <&reg_5v>;
-       status = "okay";
-};
-
-&ecspi4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi4>;
-       cs-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>, <&gpio4 3 GPIO_ACTIVE_LOW>;
-       status = "okay";
-
-       spidev0: spi@0 {
-               compatible = "spidev";
-               reg = <0>;
-               spi-max-frequency = <5000000>;
-       };
-
-       spidev1: spi@1 {
-               compatible = "spidev";
-               reg = <1>;
-               spi-max-frequency = <5000000>;
-       };
-};
-
-&i2c1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1>;
-       clock_frequency = <400000>;
-       status = "okay";
-};
-
-&i2c2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2>;
-       clock_frequency = <400000>;
-       status = "okay";
-};
-
-&lcdif {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_lcdif>;
-       status = "okay";
-
-       port {
-               lcdif_out: endpoint {
-                       remote-endpoint = <&panel_in>;
-               };
-       };
-};
-
-&pwm3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pwm3>;
-       status = "okay";
-};
-
-&snvs_pwrkey {
-       status = "disabled";
-};
-
-&tsc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_tsc>;
-       xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
-       measure-delay-time = <0xffff>;
-       pre-charge-time = <0xffff>;
-       status = "okay";
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1>;
-       status = "okay";
-};
-
-&uart2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2>;
-       status = "okay";
-};
-
-&usbotg1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg1_id>;
-       vbus-supply = <&reg_usbotg1_vbus>;
-       dr_mode = "otg";
-       disable-over-current;
-       status = "okay";
-};
-
-&usbotg2 {
-       vbus-supply = <&reg_usbotg2_vbus>;
-       dr_mode = "host";
-       disable-over-current;
-       status = "okay";
+       model = "Armadeus Systems OPOS6UL SoM (i.MX6UL) on OPOS6ULDev board";
+       compatible = "armadeus,imx6ul-opos6uldev", "armadeus,imx6ul-opos6ul", "fsl,imx6ul";
 };
 
 &iomuxc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gpios>;
+       pinctrl-0 = <&pinctrl_gpios>, <&pinctrl_tamper_gpios>;
 
-       pinctrl_ecspi4: ecspi4grp {
+       pinctrl_tamper_gpios: tampergpiosgrp {
                fsl,pins = <
-                       MX6UL_PAD_NAND_DATA04__ECSPI4_SCLK      0x1b0b0
-                       MX6UL_PAD_NAND_DATA05__ECSPI4_MOSI      0x1b0b0
-                       MX6UL_PAD_NAND_DATA06__ECSPI4_MISO      0x1b0b0
-                       MX6UL_PAD_NAND_DATA01__GPIO4_IO03       0x1b0b0
-                       MX6UL_PAD_NAND_DATA07__GPIO4_IO09       0x1b0b0
-               >;
-       };
-
-       pinctrl_flexcan1: flexcan1grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX      0x0b0b0
-                       MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX      0x0b0b0
-               >;
-       };
-
-       pinctrl_flexcan2: flexcan2grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX      0x0b0b0
-                       MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX      0x0b0b0
-               >;
-       };
-
-       pinctrl_gpios: gpiosgrp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x0b0b0
-                       MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25     0x0b0b0
-                       MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24     0x0b0b0
-                       MX6UL_PAD_NAND_RE_B__GPIO4_IO00         0x0b0b0
-                       MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0x0b0b0
-                       MX6UL_PAD_UART1_CTS_B__GPIO1_IO18       0x0b0b0
-                       MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x0b0b0
-                       MX6UL_PAD_NAND_WE_B__GPIO4_IO01         0x0b0b0
                        MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x0b0b0
                        MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02      0x0b0b0
                        MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x0b0b0
                >;
        };
 
-       pinctrl_gpio_keys: gpiokeysgrp {
-               fsl,pins = <
-                       MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11    0x0b0b0
-               >;
-       };
-
-       pinctrl_i2c1: i2c1grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART4_RX_DATA__I2C1_SDA       0x4001b8b0
-                       MX6UL_PAD_UART4_TX_DATA__I2C1_SCL       0x4001b8b0
-               >;
-       };
-
-       pinctrl_i2c2: i2c2grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART5_RX_DATA__I2C2_SDA       0x4001b8b0
-                       MX6UL_PAD_UART5_TX_DATA__I2C2_SCL       0x4001b8b0
-               >;
-       };
-
-       pinctrl_lcdif: lcdifgrp {
-               fsl,pins = <
-                       MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x100b1
-                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x100b1
-                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x100b1
-                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x100b1
-                       MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x100b1
-                       MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x100b1
-                       MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x100b1
-                       MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x100b1
-                       MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x100b1
-                       MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x100b1
-                       MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x100b1
-                       MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x100b1
-                       MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x100b1
-                       MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x100b1
-                       MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x100b1
-                       MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x100b1
-                       MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x100b1
-                       MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x100b1
-                       MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x100b1
-                       MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x100b1
-                       MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x100b1
-                       MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x100b1
-               >;
-       };
-
-       pinctrl_led: ledgrp {
-               fsl,pins = <
-                       MX6UL_PAD_LCD_RESET__GPIO3_IO04         0x0b0b0
-               >;
-       };
-
-       pinctrl_pwm3: pwm3grp {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_ALE__PWM3_OUT            0x1b0b0
-               >;
-       };
-
-       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
-                       MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX   0x1b0b1
-               >;
-       };
-
-       pinctrl_uart2: uart2grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX   0x1b0b1
-                       MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX   0x1b0b1
-               >;
-       };
-
-       pinctrl_usbotg1_id: usbotg1idgrp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID    0x1b0b0
-               >;
-       };
-
-       pinctrl_usbotg1_vbus: usbotg1vbusgrp {
-               fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO05__GPIO1_IO05        0x1b0b0
-               >;
-       };
-
        pinctrl_usbotg2_vbus: usbotg2vbusgrp {
                fsl,pins = <
                        MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09      0x1b0b0
index 41f3b7f..88f631c 100644 (file)
@@ -20,7 +20,7 @@
         * Set the minimum memory size here and
         * let the bootloader set the real size.
         */
-       memory {
+       memory@80000000 {
                device_type = "memory";
                reg = <0x80000000 0x8000000>;
        };
index f008036..d9fdca1 100644 (file)
 
                        anatop: anatop@20c8000 {
                                compatible = "fsl,imx6ul-anatop", "fsl,imx6q-anatop",
-                                            "syscon", "simple-bus";
+                                            "syscon", "simple-mfd";
                                reg = <0x020c8000 0x1000>;
                                interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
                                clocks = <&clks IMX6UL_CLK_GPT2_BUS>,
                                         <&clks IMX6UL_CLK_GPT2_SERIAL>;
                                clock-names = "ipg", "per";
+                               status = "disabled";
                        };
 
                        sdma: sdma@20ec000 {
index b6147c7..a78849f 100644 (file)
@@ -8,6 +8,20 @@
                stdout-path = "serial0:115200n8";
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_snvs_gpiokeys>;
+
+               power {
+                       label = "Wake-Up";
+                       gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_WAKEUP>;
+                       debounce-interval = <10>;
+                       wakeup-source;
+               };
+       };
+
        /* fixed crystal dedicated to mcp2515 */
        clk16m: clk16m {
                compatible = "fixed-clock";
index fb213be..95a11b8 100644 (file)
@@ -15,7 +15,7 @@
 &iomuxc {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
-               &pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio6>;
+               &pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio6 &pinctrl_gpio7>;
 };
 
 &iomuxc_snvs {
index 038d8c9..a054543 100644 (file)
@@ -26,7 +26,7 @@
 &iomuxc {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
-               &pinctrl_gpio4 &pinctrl_gpio5>;
+               &pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio7>;
 
 };
 
index d56728f..6d850d9 100644 (file)
        vref-supply = <&reg_module_3v3_avdd>;
 };
 
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "disabled";
+};
+
+&can2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       status = "disabled";
+};
+
 /* Colibri SPI */
 &ecspi1 {
        cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>;
@@ -62,8 +74,9 @@
 };
 
 &fec2 {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "sleep";
        pinctrl-0 = <&pinctrl_enet2>;
+       pinctrl-1 = <&pinctrl_enet2_sleep>;
        phy-mode = "rmii";
        phy-handle = <&ethphy1>;
        status = "okay";
        assigned-clock-rates = <0>, <198000000>;
 };
 
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+};
+
 &iomuxc {
        pinctrl_can_int: canint-grp {
                fsl,pins = <
                >;
        };
 
+       pinctrl_enet2_sleep: enet2sleepgrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO06__GPIO1_IO06        0x0
+                       MX6UL_PAD_GPIO1_IO07__GPIO1_IO07        0x0
+                       MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08    0x0
+                       MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09    0x0
+                       MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10       0x0
+                       MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15       0x0
+                       MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b031
+                       MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11    0x0
+                       MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12    0x0
+                       MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13       0x0
+               >;
+       };
+
        pinctrl_ecspi1_cs: ecspi1-cs-grp {
                fsl,pins = <
                        MX6UL_PAD_LCD_DATA21__GPIO3_IO26        0x000a0
                >;
        };
 
+       pinctrl_flexcan1: flexcan1-grp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX   0x1b020
+                       MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX   0x1b020
+               >;
+       };
+
        pinctrl_flexcan2: flexcan2-grp {
                fsl,pins = <
                        MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX   0x1b020
 
        pinctrl_gpio1: gpio1-grp {
                fsl,pins = <
-                       MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00    0x74 /* SODIMM 55 */
-                       MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01    0x74 /* SODIMM 63 */
                        MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25     0X14 /* SODIMM 77 */
                        MX6UL_PAD_JTAG_TCK__GPIO1_IO14          0x14 /* SODIMM 99 */
                        MX6UL_PAD_NAND_CE1_B__GPIO4_IO14        0x14 /* SODIMM 133 */
                >;
        };
 
+       pinctrl_gpio7: gpio7-grp { /* CAN1 */
+               fsl,pins = <
+                       MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00    0x74 /* SODIMM 55 */
+                       MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01    0x74 /* SODIMM 63 */
+               >;
+       };
+
        pinctrl_gpmi_nand: gpmi-nand-grp {
                fsl,pins = <
                        MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00   0x100a9
                        MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT    0x14
                >;
        };
+
+       pinctrl_wdog: wdog-grp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
+               >;
+       };
 };
 
 &iomuxc_snvs {
 
        pinctrl_snvs_ad7879_int: snvs-ad7879-int-grp { /* TOUCH Interrupt */
                fsl,pins = <
-                       MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07     0x1b0b0
+                       MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07     0x100b0
                >;
        };
 
        pinctrl_snvs_reg_sd: snvs-reg-sd-grp {
                fsl,pins = <
-                       MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09     0x4001b8b0
+                       MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09     0x400100b0
                >;
        };
 
        pinctrl_snvs_usbc_det: snvs-usbc-det-grp {
                fsl,pins = <
-                       MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02     0x1b0b0
+                       MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02     0x130b0
                >;
        };
 
diff --git a/arch/arm/boot/dts/imx6ull-kontron-n6411-s.dts b/arch/arm/boot/dts/imx6ull-kontron-n6411-s.dts
new file mode 100644 (file)
index 0000000..57588a5
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2019 Kontron Electronics GmbH
+ */
+
+/dts-v1/;
+
+#include "imx6ull-kontron-n6411-som.dtsi"
+#include "imx6ul-kontron-n6x1x-s.dtsi"
+
+/ {
+       model = "Kontron N6411 S";
+       compatible = "kontron,imx6ull-n6411-s", "kontron,imx6ull-n6411-som",
+                    "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi b/arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi
new file mode 100644 (file)
index 0000000..b7e9842
--- /dev/null
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ */
+
+#include "imx6ull.dtsi"
+#include "imx6ul-kontron-n6x1x-som-common.dtsi"
+
+/ {
+       model = "Kontron N6411 SOM";
+       compatible = "kontron,imx6ull-n6311-som", "fsl,imx6ull";
+
+       memory@80000000 {
+               reg = <0x80000000 0x20000000>;
+               device_type = "memory";
+       };
+};
+
+&qspi {
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-nand";
+               spi-max-frequency = <104000000>;
+               spi-tx-bus-width = <4>;
+               spi-rx-bus-width = <4>;
+               reg = <0>;
+
+               partition@0 {
+                       label = "ubi1";
+                       reg = <0x00000000 0x08000000>;
+               };
+
+               partition@8000000 {
+                       label = "ubi2";
+                       reg = <0x08000000 0x18000000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ull-opos6ul.dtsi b/arch/arm/boot/dts/imx6ull-opos6ul.dtsi
new file mode 100644 (file)
index 0000000..155f941
--- /dev/null
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+//
+// Copyright 2019 Armadeus Systems <support@armadeus.com>
+
+#include "imx6ull.dtsi"
+#include "imx6ul-imx6ull-opos6ul.dtsi"
diff --git a/arch/arm/boot/dts/imx6ull-opos6uldev.dts b/arch/arm/boot/dts/imx6ull-opos6uldev.dts
new file mode 100644 (file)
index 0000000..198fdb7
--- /dev/null
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+//
+// Copyright 2019 Armadeus Systems <support@armadeus.com>
+
+/dts-v1/;
+#include "imx6ull-opos6ul.dtsi"
+#include "imx6ul-imx6ull-opos6uldev.dtsi"
+
+/ {
+       model = "Armadeus Systems OPOS6UL SoM (i.MX6ULL) on OPOS6ULDev board";
+       compatible = "armadeus,imx6ull-opos6uldev", "armadeus,imx6ull-opos6ul", "fsl,imx6ull";
+};
+
+&iomuxc_snvs {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_tamper_gpios>;
+
+       pinctrl_tamper_gpios: tampergpiosgrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00     0x0b0b0
+                       MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02     0x0b0b0
+                       MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03     0x0b0b0
+                       MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04     0x0b0b0
+                       MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05     0x0b0b0
+                       MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06     0x0b0b0
+                       MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07     0x0b0b0
+                       MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08     0x0b0b0
+               >;
+       };
+
+       pinctrl_usbotg2_vbus: usbotg2vbusgrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09     0x1b0b0
+               >;
+       };
+
+       pinctrl_w1: w1grp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01     0x0b0b0
+               >;
+       };
+};
index 3f27461..6aa123c 100644 (file)
                clock-frequency = <16000000>;
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpiokeys>;
+
+               power {
+                       label = "Wake-Up";
+                       gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_WAKEUP>;
+                       debounce-interval = <10>;
+                       wakeup-source;
+               };
+       };
+
        panel: panel {
                compatible = "edt,et057090dhu";
                backlight = <&bl>;
 &i2c4 {
        status = "okay";
 
+       /*
+        * Touchscreen is using SODIMM 28/30, also used for PWM<B>, PWM<C>,
+        * aka pwm2, pwm3. so if you enable touchscreen, disable the pwms
+        */
+       touchscreen@4a {
+               compatible = "atmel,maxtouch";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpiotouch>;
+               reg = <0x4a>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <9 IRQ_TYPE_EDGE_FALLING>;         /* SODIMM 28 */
+               reset-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;     /* SODIMM 30 */
+               status = "disabled";
+       };
+
        /* M41T0M6 real time clock on carrier board */
        rtc: m41t0m6@68 {
                compatible = "st,m41t0";
        vmmc-supply = <&reg_3v3>;
        status = "okay";
 };
+
+&iomuxc {
+       pinctrl_gpiotouch: touchgpios {
+               fsl,pins = <
+                       MX7D_PAD_GPIO1_IO09__GPIO1_IO9          0x74
+                       MX7D_PAD_GPIO1_IO10__GPIO1_IO10         0x14
+               >;
+       };
+};
index 917eb0b..d05be3f 100644 (file)
 &usdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_cd_usdhc1>;
-       no-1-8-v;
        cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
        disable-wp;
        vqmmc-supply = <&reg_LDO2>;
                >;
        };
 
+       pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+               fsl,pins = <
+                       MX7D_PAD_SD1_CMD__SD1_CMD       0x5a
+                       MX7D_PAD_SD1_CLK__SD1_CLK       0x1a
+                       MX7D_PAD_SD1_DATA0__SD1_DATA0   0x5a
+                       MX7D_PAD_SD1_DATA1__SD1_DATA1   0x5a
+                       MX7D_PAD_SD1_DATA2__SD1_DATA2   0x5a
+                       MX7D_PAD_SD1_DATA3__SD1_DATA3   0x5a
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+               fsl,pins = <
+                       MX7D_PAD_SD1_CMD__SD1_CMD       0x5b
+                       MX7D_PAD_SD1_CLK__SD1_CLK       0x1b
+                       MX7D_PAD_SD1_DATA0__SD1_DATA0   0x5b
+                       MX7D_PAD_SD1_DATA1__SD1_DATA1   0x5b
+                       MX7D_PAD_SD1_DATA2__SD1_DATA2   0x5b
+                       MX7D_PAD_SD1_DATA3__SD1_DATA3   0x5b
+               >;
+       };
+
        pinctrl_usdhc3: usdhc3grp {
                fsl,pins = <
                        MX7D_PAD_SD3_CMD__SD3_CMD               0x59
 
        pinctrl_gpio_lpsr: gpio1-grp {
                fsl,pins = <
-                       MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1     0x59
                        MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2     0x59
                        MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3     0x59
                >;
        };
 
+       pinctrl_gpiokeys: gpiokeysgrp {
+               fsl,pins = <
+                       MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1     0x19
+               >;
+       };
+
        pinctrl_i2c1: i2c1-grp {
                fsl,pins = <
                        MX7D_PAD_LPSR_GPIO1_IO05__I2C1_SDA      0x4000007f
index 9c8dd32..d8acd7c 100644 (file)
@@ -22,6 +22,7 @@
                        reg = <1>;
                        clock-frequency = <996000000>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                        cpu-idle-states = <&cpu_sleep_wait>;
                };
        };
@@ -43,7 +44,8 @@
                        opp-hz = /bits/ 64 <792000000>;
                        opp-microvolt = <1000000>;
                        clock-latency-ns = <150000>;
-                       opp-supported-hw = <0xf>, <0xf>;
+                       opp-supported-hw = <0xd>, <0xf>;
+                       opp-suspend;
                };
 
                opp-996000000 {
@@ -51,6 +53,7 @@
                        opp-microvolt = <1100000>;
                        clock-latency-ns = <150000>;
                        opp-supported-hw = <0xc>, <0xf>;
+                       opp-suspend;
                };
 
                opp-1200000000 {
@@ -58,6 +61,7 @@
                        opp-microvolt = <1225000>;
                        clock-latency-ns = <150000>;
                        opp-supported-hw = <0x8>, <0xf>;
+                       opp-suspend;
                };
        };
 
index e2e604d..1b812f4 100644 (file)
 
                        anatop: anatop@30360000 {
                                compatible = "fsl,imx7d-anatop", "fsl,imx6q-anatop",
-                                       "syscon", "simple-bus";
+                                       "syscon", "simple-mfd";
                                reg = <0x30360000 0x10000>;
                                interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
index 4245b33..a863a2b 100644 (file)
@@ -77,6 +77,8 @@
 };
 
 &usdhc0 {
+       assigned-clocks = <&pcc2 IMX7ULP_CLK_USDHC0>;
+       assigned-clock-parents = <&scg1 IMX7ULP_CLK_APLL_PFD1>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc0>;
        cd-gpios = <&gpio_ptc 10 GPIO_ACTIVE_LOW>;
index 6859a3a..d37a192 100644 (file)
                #clock-cells = <0>;
        };
 
-       mpll: clock-mpll {
-               compatible = "fixed-clock";
-               clock-frequency = <480000000>;
-               clock-output-names = "mpll";
-               #clock-cells = <0>;
-       };
-
        ahbbridge0: bus@40000000 {
                compatible = "simple-bus";
                #address-cells = <1>;
                                 <&scg1 IMX7ULP_CLK_NIC1_DIV>,
                                 <&pcc2 IMX7ULP_CLK_USDHC0>;
                        clock-names = "ipg", "ahb", "per";
-                       assigned-clocks = <&pcc2 IMX7ULP_CLK_USDHC0>;
-                       assigned-clock-parents = <&scg1 IMX7ULP_CLK_NIC1_DIV>;
                        bus-width = <4>;
                        fsl,tuning-start-tap = <20>;
                        fsl,tuning-step = <2>;
                                 <&scg1 IMX7ULP_CLK_NIC1_DIV>,
                                 <&pcc2 IMX7ULP_CLK_USDHC1>;
                        clock-names = "ipg", "ahb", "per";
-                       assigned-clocks = <&pcc2 IMX7ULP_CLK_USDHC1>;
-                       assigned-clock-parents = <&scg1 IMX7ULP_CLK_NIC1_DIV>;
                        bus-width = <4>;
                        fsl,tuning-start-tap = <20>;
                        fsl,tuning-step = <2>;
                        compatible = "fsl,imx7ulp-scg1";
                        reg = <0x403e0000 0x10000>;
                        clocks = <&rosc>, <&sosc>, <&sirc>,
-                                <&firc>, <&upll>, <&mpll>;
+                                <&firc>, <&upll>;
                        clock-names = "rosc", "sosc", "sirc",
-                                     "firc", "upll", "mpll";
+                                     "firc", "upll";
                        #clock-cells = <1>;
                };
 
+               wdog1: watchdog@403d0000 {
+                       compatible = "fsl,imx7ulp-wdt";
+                       reg = <0x403d0000 0x10000>;
+                       interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
+                       assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
+                       assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
+                       timeout-sec = <40>;
+               };
+
                pcc2: clock-controller@403f0000 {
                        compatible = "fsl,imx7ulp-pcc2";
                        reg = <0x403f0000 0x10000>;
                                 <&scg1 IMX7ULP_CLK_APLL_PFD0>,
                                 <&scg1 IMX7ULP_CLK_UPLL>,
                                 <&scg1 IMX7ULP_CLK_SOSC_BUS_CLK>,
-                                <&scg1 IMX7ULP_CLK_MIPI_PLL>,
                                 <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>,
                                 <&scg1 IMX7ULP_CLK_ROSC>,
                                 <&scg1 IMX7ULP_CLK_SPLL_BUS_CLK>;
                        clock-names = "nic1_bus_clk", "nic1_clk", "ddr_clk",
                                      "apll_pfd2", "apll_pfd1", "apll_pfd0",
-                                     "upll", "sosc_bus_clk", "mpll",
+                                     "upll", "sosc_bus_clk",
                                      "firc_bus_clk", "rosc", "spll_bus_clk";
                        assigned-clocks = <&pcc2 IMX7ULP_CLK_LPTPM5>;
                        assigned-clock-parents = <&scg1 IMX7ULP_CLK_SOSC_BUS_CLK>;
                                 <&scg1 IMX7ULP_CLK_APLL_PFD0>,
                                 <&scg1 IMX7ULP_CLK_UPLL>,
                                 <&scg1 IMX7ULP_CLK_SOSC_BUS_CLK>,
-                                <&scg1 IMX7ULP_CLK_MIPI_PLL>,
                                 <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>,
                                 <&scg1 IMX7ULP_CLK_ROSC>,
                                 <&scg1 IMX7ULP_CLK_SPLL_BUS_CLK>;
                        clock-names = "nic1_bus_clk", "nic1_clk", "ddr_clk",
                                      "apll_pfd2", "apll_pfd1", "apll_pfd0",
-                                     "upll", "sosc_bus_clk", "mpll",
+                                     "upll", "sosc_bus_clk",
                                      "firc_bus_clk", "rosc", "spll_bus_clk";
                };
        };
index 457515b..0397c34 100644 (file)
@@ -408,4 +408,31 @@ clocks {
                reg-names = "control", "domain";
                domain-id = <0>;
        };
+
+       /*
+        * Below are set of fixed, input clocks definitions,
+        * for which real frequencies have to be defined in board files.
+        * Those clocks can be used as reference clocks for some HW modules
+        * (as cpts, for example) by configuring corresponding clock muxes.
+        */
+       timi0: timi0 {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+               clock-output-names = "timi0";
+       };
+
+       timi1: timi1 {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+               clock-output-names = "timi1";
+       };
+
+       tsrefclk: tsrefclk {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+               clock-output-names = "tsrefclk";
+       };
 };
index f759215..cf30e00 100644 (file)
@@ -71,4 +71,24 @@ clocks {
                reg-names = "control", "domain";
                domain-id = <29>;
        };
+
+       /*
+        * Below are set of fixed, input clocks definitions,
+        * for which real frequencies have to be defined in board files.
+        * Those clocks can be used as reference clocks for some HW modules
+        * (as cpts, for example) by configuring corresponding clock muxes.
+        */
+       tsipclka: tsipclka {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+               clock-output-names = "tsipclka";
+       };
+
+       tsipclkb: tsipclkb {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+               clock-output-names = "tsipclkb";
+       };
 };
index 1db17ec..ad15e77 100644 (file)
@@ -135,8 +135,8 @@ netcp: netcp@24000000 {
        /* NetCP address range */
        ranges = <0 0x24000000 0x1000000>;
 
-       clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>;
-       clock-names = "pa_clk", "ethss_clk", "cpts";
+       clocks = <&clkpa>, <&clkcpgmac>;
+       clock-names = "pa_clk", "ethss_clk";
        dma-coherent;
 
        ti,navigator-dmas = <&dma_gbe 0>,
@@ -156,6 +156,23 @@ netcp: netcp@24000000 {
                        tx-queue = <896>;
                        tx-channel = "nettx";
 
+                       cpts {
+                               clocks = <&cpts_refclk_mux>;
+                               clock-names = "cpts";
+
+                               cpts_refclk_mux: cpts-refclk-mux {
+                                       #clock-cells = <0>;
+                                       clocks = <&chipclk12>, <&chipclk13>,
+                                                <&timi0>, <&timi1>,
+                                                <&tsipclka>, <&tsrefclk>,
+                                                <&tsipclkb>;
+                                       ti,mux-tbl = <0x0>, <0x1>, <0x2>,
+                                               <0x3>, <0x4>, <0x8>, <0xC>;
+                                       assigned-clocks = <&cpts_refclk_mux>;
+                                       assigned-clock-parents = <&chipclk12>;
+                               };
+                       };
+
                        interfaces {
                                gbe0: interface-0 {
                                        slave-port = <0>;
index e203145..d5a6c1f 100644 (file)
@@ -152,8 +152,8 @@ netcp: netcp@2000000 {
        /* NetCP address range */
        ranges  = <0 0x2000000 0x100000>;
 
-       clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>;
-       clock-names = "pa_clk", "ethss_clk", "cpts";
+       clocks = <&clkpa>, <&clkcpgmac>;
+       clock-names = "pa_clk", "ethss_clk";
        dma-coherent;
 
        ti,navigator-dmas = <&dma_gbe 22>,
@@ -175,6 +175,22 @@ netcp: netcp@2000000 {
                        tx-queue = <648>;
                        tx-channel = "nettx";
 
+                       cpts {
+                               clocks = <&cpts_refclk_mux>;
+                               clock-names = "cpts";
+
+                               cpts_refclk_mux: cpts-refclk-mux {
+                                       #clock-cells = <0>;
+                                       clocks = <&chipclk12>, <&chipclk13>,
+                                                <&timi0>, <&timi1>,
+                                                <&tsrefclk>;
+                                       ti,mux-tbl = <0x0>, <0x1>, <0x2>,
+                                               <0x3>, <0x8>;
+                                       assigned-clocks = <&cpts_refclk_mux>;
+                                       assigned-clock-parents = <&chipclk12>;
+                               };
+                       };
+
                        interfaces {
                                gbe0: interface-0 {
                                        slave-port = <0>;
index a2e47ba..c1f9826 100644 (file)
@@ -134,8 +134,8 @@ netcp: netcp@26000000 {
        /* NetCP address range */
        ranges = <0 0x26000000 0x1000000>;
 
-       clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>;
-       clock-names = "pa_clk", "ethss_clk", "cpts";
+       clocks = <&clkpa>, <&clkcpgmac>;
+       clock-names = "pa_clk", "ethss_clk";
        dma-coherent;
 
        ti,navigator-dmas = <&dma_gbe 0>,
@@ -155,6 +155,22 @@ netcp: netcp@26000000 {
                        tx-queue = <896>;
                        tx-channel = "nettx";
 
+                       cpts {
+                               clocks = <&cpts_refclk_mux>;
+                               clock-names = "cpts";
+
+                               cpts_refclk_mux: cpts-refclk-mux {
+                                       #clock-cells = <0>;
+                                       clocks = <&chipclk12>, <&chipclk13>,
+                                                <&timi0>, <&timi1>,
+                                                <&tsrefclk>;
+                                       ti,mux-tbl = <0x0>, <0x1>, <0x2>,
+                                               <0x3>, <0x8>;
+                                       assigned-clocks = <&cpts_refclk_mux>;
+                                       assigned-clock-parents = <&chipclk12>;
+                               };
+                       };
+
                        interfaces {
                                gbe0: interface-0 {
                                        slave-port = <0>;
index c97ed29..217bd37 100644 (file)
 
                        rs5c372: rs5c372@32 {
                                status = "disabled";
-                               compatible = "ricoh,rs5c372";
+                               compatible = "ricoh,rs5c372a";
                                reg = <0x32>;
                        };
 
index 07ac99b..b553613 100644 (file)
 #include "logicpd-torpedo-37xx-devkit.dts"
 
 &lcd0 {
-
-       label = "28";
-
-       panel-timing {
-               clock-frequency = <9000000>;
-               hactive = <480>;
-               vactive = <272>;
-               hfront-porch = <3>;
-               hback-porch = <2>;
-               hsync-len = <42>;
-               vback-porch = <3>;
-               vfront-porch = <2>;
-               vsync-len = <11>;
-               hsync-active = <1>;
-               vsync-active = <1>;
-               de-active = <1>;
-               pixelclk-active = <0>;
-       };
+       compatible = "logicpd,type28";
 };
index 18c27e8..5532db0 100644 (file)
        };
 };
 
+&uart2 {
+       /delete-property/dma-names;
+       bluetooth {
+               compatible = "ti,wl1283-st";
+               enable-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio 162 */
+               max-speed = <3000000>;
+       };
+};
+
+/* The DM3730 has a faster L3 than OMAP35, so increase pixel clock */
+&mt9p031_out {
+       pixel-clock-frequency = <90000000>;
+};
+
 &omap3_pmx_core {
        mmc3_pins: pinmux_mm3_pins {
                pinctrl-single,pins = <
index 449cc76..f7b82ce 100644 (file)
        };
 };
 
+&hdqw1w {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdq_pins>;
+};
+
+
 &vpll2 {
        regulator-always-on;
 };
 &dss {
        status = "ok";
        vdds_dsi-supply = <&vpll2>;
+       vdda_video-supply = <&vpll2>;
        pinctrl-names = "default";
        pinctrl-0 = <&dss_dpi_pins1>;
        port {
 
        lcd0: display {
                /* This isn't the exact LCD, but the timings meet spec */
-               /* To make it work, set CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=4 */
                compatible = "newhaven,nhd-4.3-480272ef-atxl";
                label = "15";
                pinctrl-names = "default";
                >;
        };
 
+       hdq_pins: hdq_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21c6, PIN_INPUT_PULLUP | MUX_MODE0) /* hdq_sio */
+               >;
+       };
+
        pwm_pins: pinmux_pwm_pins {
                pinctrl-single,pins = <
                        OMAP3_CORE1_IOPAD(0x20B8, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE3)       /* gpmc_ncs5.gpt_10_pwm_evt */
index 506b118..3a52285 100644 (file)
        };
 };
 
+/* The Torpedo doesn't route the USB host pins */
+&usbhshost {
+       status = "disabled";
+};
+
 &gpmc {
        ranges = <0 0 0x30000000 0x1000000>;    /* CS0: 16MB for NAND */
 
diff --git a/arch/arm/boot/dts/mmp3-dell-ariel.dts b/arch/arm/boot/dts/mmp3-dell-ariel.dts
new file mode 100644 (file)
index 0000000..c1947b5
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Dell Wyse 3020 a.k.a. "Ariel" a.k.a. Tx0D (T00D, T10D)
+ *
+ * Copyright (C) 2019 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+/dts-v1/;
+#include "mmp3.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       model = "Dell Ariel";
+       compatible = "dell,wyse-ariel", "marvell,mmp3";
+
+       aliases {
+               serial2 = &uart3;
+       };
+
+       chosen {
+               #address-cells = <0x1>;
+               #size-cells = <0x1>;
+               ranges;
+               bootargs = "earlyprintk=ttyS2,115200 console=ttyS2,115200";
+       };
+
+       memory@0 {
+               linux,usable-memory = <0x0 0x7f600000>;
+               available = <0x7f700000 0x7ff00000 0x00000000 0x7f600000>;
+               reg = <0x0 0x80000000>;
+               device_type = "memory";
+       };
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&rtc {
+       status = "okay";
+};
+
+&usb_otg0 {
+       status = "okay";
+};
+
+&usb_otg_phy0 {
+       status = "okay";
+};
+
+&mmc3 {
+       status = "okay";
+       max-frequency = <50000000>;
+       status = "okay";
+       bus-width = <8>;
+       non-removable;
+       cap-mmc-highspeed;
+};
+
+&twsi1 {
+       status = "okay";
+
+       rtc@68 {
+               compatible = "dallas,ds1338";
+               reg = <0x68>;
+               status = "okay";
+       };
+};
+
+&twsi3 {
+       status = "okay";
+};
+
+&twsi4 {
+       status = "okay";
+};
+
+&ssp3 {
+       status = "okay";
+       cs-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
+
+       firmware-flash@0 {
+               compatible = "st,m25p80", "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <40000000>;
+               m25p,fast-read;
+       };
+};
+
+&ssp4 {
+       cs-gpios = <&gpio 56 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/mmp3.dtsi b/arch/arm/boot/dts/mmp3.dtsi
new file mode 100644 (file)
index 0000000..d9762de
--- /dev/null
@@ -0,0 +1,527 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ *  Copyright (C) 2019 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <dt-bindings/clock/marvell,mmp2.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               enable-method = "marvell,mmp3-smp";
+
+               cpu@0 {
+                       compatible = "marvell,pj4b";
+                       device_type = "cpu";
+                       next-level-cache = <&l2>;
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "marvell,pj4b";
+                       device_type = "cpu";
+                       next-level-cache = <&l2>;
+                       reg = <1>;
+               };
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&gic>;
+               ranges;
+
+               axi@d4200000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xd4200000 0x00200000>;
+                       ranges;
+
+                       interrupt-controller@d4282000 {
+                               compatible = "marvell,mmp3-intc";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0xd4282000 0x1000>,
+                                     <0xd4284000 0x100>;
+                               mrvl,intc-nr-irqs = <64>;
+                       };
+
+                       pmic_mux: interrupt-controller@d4282150 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x150 0x4>, <0x168 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <4>;
+                       };
+
+                       rtc_mux: interrupt-controller@d4282154 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x154 0x4>, <0x16c 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <2>;
+                       };
+
+                       hsi3_mux: interrupt-controller@d42821bc {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x1bc 0x4>, <0x1a4 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <3>;
+                       };
+
+                       gpu_mux: interrupt-controller@d42821c0 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x1c0 0x4>, <0x1a8 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <3>;
+                       };
+
+                       twsi_mux: interrupt-controller@d4282158 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x158 0x4>, <0x170 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <5>;
+                       };
+
+                       hsi2_mux: interrupt-controller@d42821c4 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x1c4 0x4>, <0x1ac 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <2>;
+                       };
+
+                       dxo_mux: interrupt-controller@d42821c8 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x1c8 0x4>, <0x1b0 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <2>;
+                       };
+
+                       misc1_mux: interrupt-controller@d428215c {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x15c 0x4>, <0x174 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <31>;
+                       };
+
+                       ci_mux: interrupt-controller@d42821cc {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x1cc 0x4>, <0x1b4 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <2>;
+                       };
+
+                       ssp_mux: interrupt-controller@d4282160 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x160 0x4>, <0x178 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <2>;
+                       };
+
+                       hsi1_mux: interrupt-controller@d4282184 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x184 0x4>, <0x17c 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <4>;
+                       };
+
+                       misc2_mux: interrupt-controller@d4282188 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x188 0x4>, <0x180 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <20>;
+                       };
+
+                       hsi0_mux: interrupt-controller@d42821d0 {
+                               compatible = "mrvl,mmp2-mux-intc";
+                               interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x1d0 0x4>, <0x1b8 0x4>;
+                               reg-names = "mux status", "mux mask";
+                               mrvl,intc-nr-irqs = <5>;
+                       };
+
+                       usb_otg_phy0: usb-otg-phy@d4207000 {
+                               compatible = "marvell,mmp3-usb-phy";
+                               reg = <0xd4207000 0x40>;
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       usb_otg0: usb-otg@d4208000 {
+                               compatible = "marvell,pxau2o-ehci";
+                               reg = <0xd4208000 0x200>;
+                               interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_USB>;
+                               clock-names = "USBCLK";
+                               phys = <&usb_otg_phy0>;
+                               phy-names = "usb";
+                               status = "disabled";
+                       };
+
+                       mmc1: mmc@d4280000 {
+                               compatible = "mrvl,pxav3-mmc";
+                               reg = <0xd4280000 0x120>;
+                               clocks = <&soc_clocks MMP2_CLK_SDH0>;
+                               clock-names = "io";
+                               interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       mmc2: mmc@d4280800 {
+                               compatible = "mrvl,pxav3-mmc";
+                               reg = <0xd4280800 0x120>;
+                               clocks = <&soc_clocks MMP2_CLK_SDH1>;
+                               clock-names = "io";
+                               interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       mmc3: mmc@d4281000 {
+                               compatible = "mrvl,pxav3-mmc";
+                               reg = <0xd4281000 0x120>;
+                               clocks = <&soc_clocks MMP2_CLK_SDH2>;
+                               clock-names = "io";
+                               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       mmc4: mmc@d4281800 {
+                               compatible = "mrvl,pxav3-mmc";
+                               reg = <0xd4281800 0x120>;
+                               clocks = <&soc_clocks MMP2_CLK_SDH3>;
+                               clock-names = "io";
+                               interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       camera0: camera@d420a000 {
+                               compatible = "marvell,mmp2-ccic";
+                               reg = <0xd420a000 0x800>;
+                               interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_CCIC0>;
+                               clock-names = "axi";
+                               #clock-cells = <0>;
+                               clock-output-names = "mclk";
+                               status = "disabled";
+                       };
+
+                       camera1: camera@d420a800 {
+                               compatible = "marvell,mmp2-ccic";
+                               reg = <0xd420a800 0x800>;
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_CCIC1>;
+                               clock-names = "axi";
+                               #clock-cells = <0>;
+                               clock-output-names = "mclk";
+                               status = "disabled";
+                       };
+               };
+
+               apb@d4000000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xd4000000 0x00200000>;
+                       ranges;
+
+                       timer: timer@d4014000 {
+                               compatible = "mrvl,mmp-timer";
+                               reg = <0xd4014000 0x100>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_TIMER>;
+                       };
+
+                       uart1: uart@d4030000 {
+                               compatible = "mrvl,mmp-uart";
+                               reg = <0xd4030000 0x1000>;
+                               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_UART0>;
+                               resets = <&soc_clocks MMP2_CLK_UART0>;
+                               reg-shift = <2>;
+                               status = "disabled";
+                       };
+
+                       uart2: uart@d4017000 {
+                               compatible = "mrvl,mmp-uart";
+                               reg = <0xd4017000 0x1000>;
+                               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_UART1>;
+                               resets = <&soc_clocks MMP2_CLK_UART1>;
+                               reg-shift = <2>;
+                               status = "disabled";
+                       };
+
+                       uart3: uart@d4018000 {
+                               compatible = "mrvl,mmp-uart";
+                               reg = <0xd4018000 0x1000>;
+                               interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_UART2>;
+                               resets = <&soc_clocks MMP2_CLK_UART2>;
+                               reg-shift = <2>;
+                               status = "disabled";
+                       };
+
+                       uart4: uart@d4016000 {
+                               compatible = "mrvl,mmp-uart";
+                               reg = <0xd4016000 0x1000>;
+                               interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_UART3>;
+                               resets = <&soc_clocks MMP2_CLK_UART3>;
+                               reg-shift = <2>;
+                               status = "disabled";
+                       };
+
+                       gpio: gpio@d4019000 {
+                               compatible = "marvell,mmp2-gpio";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xd4019000 0x1000>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "gpio_mux";
+                               clocks = <&soc_clocks MMP2_CLK_GPIO>;
+                               resets = <&soc_clocks MMP2_CLK_GPIO>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               ranges;
+
+                               gcb0: gpio@d4019000 {
+                                       reg = <0xd4019000 0x4>;
+                               };
+
+                               gcb1: gpio@d4019004 {
+                                       reg = <0xd4019004 0x4>;
+                               };
+
+                               gcb2: gpio@d4019008 {
+                                       reg = <0xd4019008 0x4>;
+                               };
+
+                               gcb3: gpio@d4019100 {
+                                       reg = <0xd4019100 0x4>;
+                               };
+
+                               gcb4: gpio@d4019104 {
+                                       reg = <0xd4019104 0x4>;
+                               };
+
+                               gcb5: gpio@d4019108 {
+                                       reg = <0xd4019108 0x4>;
+                               };
+                       };
+
+                       twsi1: i2c@d4011000 {
+                               compatible = "mrvl,mmp-twsi";
+                               reg = <0xd4011000 0x1000>;
+                               interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI0>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               mrvl,i2c-fast-mode;
+                               status = "disabled";
+                       };
+
+                       twsi2: i2c@d4031000 {
+                               compatible = "mrvl,mmp-twsi";
+                               reg = <0xd4031000 0x1000>;
+                               interrupt-parent = <&twsi_mux>;
+                               interrupts = <0>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI1>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI1>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       twsi3: i2c@d4032000 {
+                               compatible = "mrvl,mmp-twsi";
+                               reg = <0xd4032000 0x1000>;
+                               interrupt-parent = <&twsi_mux>;
+                               interrupts = <1>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI2>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI2>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       twsi4: i2c@d4033000 {
+                               compatible = "mrvl,mmp-twsi";
+                               reg = <0xd4033000 0x1000>;
+                               interrupt-parent = <&twsi_mux>;
+                               interrupts = <2>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI3>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI3>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+
+                       twsi5: i2c@d4033800 {
+                               compatible = "mrvl,mmp-twsi";
+                               reg = <0xd4033800 0x1000>;
+                               interrupt-parent = <&twsi_mux>;
+                               interrupts = <3>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI4>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI4>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       twsi6: i2c@d4034000 {
+                               compatible = "mrvl,mmp-twsi";
+                               reg = <0xd4034000 0x1000>;
+                               interrupt-parent = <&twsi_mux>;
+                               interrupts = <4>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI5>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI5>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       rtc: rtc@d4010000 {
+                               compatible = "mrvl,mmp-rtc";
+                               reg = <0xd4010000 0x1000>;
+                               interrupts = <1 0>;
+                               interrupt-names = "rtc 1Hz", "rtc alarm";
+                               interrupt-parent = <&rtc_mux>;
+                               clocks = <&soc_clocks MMP2_CLK_RTC>;
+                               resets = <&soc_clocks MMP2_CLK_RTC>;
+                               status = "disabled";
+                       };
+
+                       ssp1: spi@d4035000 {
+                               compatible = "marvell,mmp2-ssp";
+                               reg = <0xd4035000 0x1000>;
+                               clocks = <&soc_clocks MMP2_CLK_SSP0>;
+                               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       ssp2: spi@d4036000 {
+                               compatible = "marvell,mmp2-ssp";
+                               reg = <0xd4036000 0x1000>;
+                               clocks = <&soc_clocks MMP2_CLK_SSP1>;
+                               interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       ssp3: spi@d4037000 {
+                               compatible = "marvell,mmp2-ssp";
+                               reg = <0xd4037000 0x1000>;
+                               clocks = <&soc_clocks MMP2_CLK_SSP2>;
+                               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       ssp4: spi@d4039000 {
+                               compatible = "marvell,mmp2-ssp";
+                               reg = <0xd4039000 0x1000>;
+                               clocks = <&soc_clocks MMP2_CLK_SSP3>;
+                               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+               };
+
+               l2: l2-cache-controller@d0020000 {
+                       compatible = "marvell,tauros3-cache", "arm,pl310-cache";
+                       reg = <0xd0020000 0x1000>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               soc_clocks: clocks@d4050000 {
+                       compatible = "marvell,mmp2-clock";
+                       reg = <0xd4050000 0x1000>,
+                             <0xd4282800 0x400>,
+                             <0xd4015000 0x1000>;
+                       reg-names = "mpmu", "apmu", "apbc";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+               };
+
+               snoop-control-unit@e0000000 {
+                       compatible = "arm,arm11mp-scu";
+                       reg = <0xe0000000 0x100>;
+               };
+
+               gic: interrupt-controller@e0001000 {
+                       compatible = "arm,arm11mp-gic";
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       reg = <0xe0001000 0x1000>,
+                             <0xe0000100 0x100>;
+               };
+
+               local-timer@e0000600 {
+                       compatible = "arm,arm11mp-twd-timer";
+                       interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+                                                 IRQ_TYPE_EDGE_RISING)>;
+                       reg = <0xe0000600 0x20>;
+               };
+
+               watchdog@e0000620 {
+                       compatible = "arm,arm11mp-twd-wdt";
+                       reg = <0xe0000620 0x20>;
+                       interrupts = <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
+                                                 IRQ_TYPE_EDGE_RISING)>;
+               };
+       };
+};
index 08bae93..936ad01 100644 (file)
                regulator-enable-ramp-delay = <1000>;
        };
 
-       /* Used by DSS */
+       /* Used by DSS and is the "zerov_regulator" trigger for SoC off mode */
        vcsi: VCSI {
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
                regulator-enable-ramp-delay = <1000>;
-               regulator-boot-on;
+               regulator-always-on;
        };
 
        vdac: VDAC {
diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
new file mode 100644 (file)
index 0000000..da6b107
--- /dev/null
@@ -0,0 +1,786 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "omap443x.dtsi"
+#include "motorola-cpcap-mapphone.dtsi"
+
+/ {
+       chosen {
+               stdout-path = &uart3;
+       };
+
+       aliases {
+               display0 = &lcd0;
+               display1 = &hdmi0;
+       };
+
+       /*
+        * We seem to have only 1021 MB accessible, 1021 - 1022 is locked,
+        * then 1023 - 1024 seems to contain mbm.
+        */
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x3fd00000>;  /* 1021 MB */
+       };
+
+       /* Poweroff GPIO probably connected to CPCAP */
+       gpio-poweroff {
+               compatible = "gpio-poweroff";
+               pinctrl-0 = <&poweroff_gpio>;
+               pinctrl-names = "default";
+               gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;    /* gpio50 */
+       };
+
+       hdmi0: connector {
+               compatible = "hdmi-connector";
+               pinctrl-0 = <&hdmi_hpd_gpio>;
+               pinctrl-names = "default";
+               label = "hdmi";
+               type = "d";
+
+               hpd-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>;       /* gpio63 */
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_out>;
+                       };
+               };
+       };
+
+       /*
+        * HDMI 5V regulator probably sourced from battery. Let's keep
+        * keep this as always enabled for HDMI to work until we've
+        * figured what the encoder chip is.
+        */
+       hdmi_regulator: regulator-hdmi {
+               compatible = "regulator-fixed";
+               regulator-name = "hdmi";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio2 27 GPIO_ACTIVE_HIGH>;    /* gpio59 */
+               enable-active-high;
+               regulator-always-on;
+       };
+
+       /* FS USB Host PHY on port 1 for mdm6600 */
+       fsusb1_phy: usb-phy@1 {
+               compatible = "motorola,mapphone-mdm6600";
+               pinctrl-0 = <&usb_mdm6600_pins>;
+               pinctrl-names = "default";
+               enable-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>;     /* gpio_95 */
+               power-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>;     /* gpio_54 */
+               reset-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>;     /* gpio_49 */
+               /* mode: gpio_148 gpio_149 */
+               motorola,mode-gpios = <&gpio5 20 GPIO_ACTIVE_HIGH>,
+                                     <&gpio5 21 GPIO_ACTIVE_HIGH>;
+               /* cmd: gpio_103 gpio_104 gpio_142 */
+               motorola,cmd-gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>,
+                                    <&gpio4 8 GPIO_ACTIVE_HIGH>,
+                                    <&gpio5 14 GPIO_ACTIVE_HIGH>;
+               /* status: gpio_52 gpio_53 gpio_55 */
+               motorola,status-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>,
+                                       <&gpio2 21 GPIO_ACTIVE_HIGH>,
+                                       <&gpio2 23 GPIO_ACTIVE_HIGH>;
+               #phy-cells = <0>;
+       };
+
+       /* HS USB host TLL nop-phy on port 2 for w3glte */
+       hsusb2_phy: usb-phy@2 {
+               compatible = "usb-nop-xceiv";
+               #phy-cells = <0>;
+       };
+
+       /* LCD regulator from sw5 source */
+       lcd_regulator: regulator-lcd {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd";
+               regulator-min-microvolt = <5050000>;
+               regulator-max-microvolt = <5050000>;
+               gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;     /* gpio96 */
+               enable-active-high;
+               vin-supply = <&sw5>;
+       };
+
+       /* This is probably coming straight from the battery.. */
+       wl12xx_vmmc: regulator-wl12xx {
+               compatible = "regulator-fixed";
+               regulator-name = "vwl1271";
+               regulator-min-microvolt = <1650000>;
+               regulator-max-microvolt = <1650000>;
+               gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;    /* gpio94 */
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               volume_down {
+                       label = "Volume Down";
+                       gpios = <&gpio5 26 GPIO_ACTIVE_LOW>; /* gpio154 */
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       linux,can-disable;
+                       /* Value above 7.95ms for no GPIO hardware debounce */
+                       debounce-interval = <10>;
+               };
+
+               slider {
+                       label = "Keypad Slide";
+                       gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */
+                       linux,input-type = <EV_SW>;
+                       linux,code = <SW_KEYPAD_SLIDE>;
+                       linux,can-disable;
+                       /* Value above 7.95ms for no GPIO hardware debounce */
+                       debounce-interval = <10>;
+               };
+       };
+
+       soundcard {
+               compatible = "audio-graph-card";
+               label = "Droid 4 Audio";
+
+               simple-graph-card,widgets =
+                       "Speaker", "Earpiece",
+                       "Speaker", "Loudspeaker",
+                       "Headphone", "Headphone Jack",
+                       "Microphone", "Internal Mic";
+
+               simple-graph-card,routing =
+                       "Earpiece", "EP",
+                       "Loudspeaker", "SPKR",
+                       "Headphone Jack", "HSL",
+                       "Headphone Jack", "HSR",
+                       "MICR", "Internal Mic";
+
+               dais = <&mcbsp2_port>, <&mcbsp3_port>;
+       };
+
+       pwm8: dmtimer-pwm-8 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&vibrator_direction_pin>;
+
+               compatible = "ti,omap-dmtimer-pwm";
+               #pwm-cells = <3>;
+               ti,timers = <&timer8>;
+               ti,clock-source = <0x01>;
+       };
+
+       pwm9: dmtimer-pwm-9 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&vibrator_enable_pin>;
+
+               compatible = "ti,omap-dmtimer-pwm";
+               #pwm-cells = <3>;
+               ti,timers = <&timer9>;
+               ti,clock-source = <0x01>;
+       };
+
+       vibrator {
+               compatible = "pwm-vibrator";
+               pwms = <&pwm9 0 10000000 0>, <&pwm8 0 10000000 0>;
+               pwm-names = "enable", "direction";
+               direction-duty-cycle-ns = <10000000>;
+       };
+};
+
+&dss {
+       status = "okay";
+};
+
+&dsi1 {
+       status = "okay";
+       vdd-supply = <&vcsi>;
+
+       port {
+               dsi1_out_ep: endpoint {
+                       remote-endpoint = <&lcd0_in>;
+                       lanes = <0 1 2 3 4 5>;
+               };
+       };
+
+       lcd0: display {
+               compatible = "panel-dsi-cm";
+               label = "lcd0";
+               vddi-supply = <&lcd_regulator>;
+               reset-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>;      /* gpio101 */
+
+               width-mm = <50>;
+               height-mm = <89>;
+
+               panel-timing {
+                       clock-frequency = <0>;          /* Calculated by dsi */
+
+                       hback-porch = <2>;
+                       hactive = <540>;
+                       hfront-porch = <0>;
+                       hsync-len = <2>;
+
+                       vback-porch = <1>;
+                       vactive = <960>;
+                       vfront-porch = <0>;
+                       vsync-len = <1>;
+
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <1>;
+               };
+
+               port {
+                       lcd0_in: endpoint {
+                               remote-endpoint = <&dsi1_out_ep>;
+                       };
+               };
+       };
+};
+
+&hdmi {
+       status = "okay";
+       pinctrl-0 = <&dss_hdmi_pins>;
+       pinctrl-names = "default";
+       vdda-supply = <&vdac>;
+
+       port {
+               hdmi_out: endpoint {
+                       remote-endpoint = <&hdmi_connector_in>;
+                       lanes = <1 0 3 2 5 4 7 6>;
+               };
+       };
+};
+
+&i2c1 {
+       tmp105@48 {
+               compatible = "ti,tmp105";
+               reg = <0x48>;
+               pinctrl-0 = <&tmp105_irq>;
+               pinctrl-names = "default";
+               /* kpd_row0.gpio_178 */
+               interrupts-extended = <&gpio6 18 IRQ_TYPE_EDGE_FALLING
+                                      &omap4_pmx_core 0x14e>;
+               interrupt-names = "irq", "wakeup";
+               wakeup-source;
+       };
+};
+
+&keypad {
+       keypad,num-rows = <8>;
+       keypad,num-columns = <8>;
+       linux,keymap = <
+
+       /* Row 1 */
+       MATRIX_KEY(0, 2, KEY_1)
+       MATRIX_KEY(0, 6, KEY_2)
+       MATRIX_KEY(2, 3, KEY_3)
+       MATRIX_KEY(0, 7, KEY_4)
+       MATRIX_KEY(0, 4, KEY_5)
+       MATRIX_KEY(5, 5, KEY_6)
+       MATRIX_KEY(0, 1, KEY_7)
+       MATRIX_KEY(0, 5, KEY_8)
+       MATRIX_KEY(0, 0, KEY_9)
+       MATRIX_KEY(1, 6, KEY_0)
+
+       /* Row 2 */
+       MATRIX_KEY(3, 4, KEY_APOSTROPHE)
+       MATRIX_KEY(7, 6, KEY_Q)
+       MATRIX_KEY(7, 7, KEY_W)
+       MATRIX_KEY(7, 2, KEY_E)
+       MATRIX_KEY(1, 0, KEY_R)
+       MATRIX_KEY(4, 4, KEY_T)
+       MATRIX_KEY(1, 2, KEY_Y)
+       MATRIX_KEY(6, 7, KEY_U)
+       MATRIX_KEY(2, 2, KEY_I)
+       MATRIX_KEY(5, 6, KEY_O)
+       MATRIX_KEY(3, 7, KEY_P)
+       MATRIX_KEY(6, 5, KEY_BACKSPACE)
+
+       /* Row 3 */
+       MATRIX_KEY(5, 4, KEY_TAB)
+       MATRIX_KEY(5, 7, KEY_A)
+       MATRIX_KEY(2, 7, KEY_S)
+       MATRIX_KEY(7, 0, KEY_D)
+       MATRIX_KEY(2, 6, KEY_F)
+       MATRIX_KEY(6, 2, KEY_G)
+       MATRIX_KEY(6, 6, KEY_H)
+       MATRIX_KEY(1, 4, KEY_J)
+       MATRIX_KEY(3, 1, KEY_K)
+       MATRIX_KEY(2, 1, KEY_L)
+       MATRIX_KEY(4, 6, KEY_ENTER)
+
+       /* Row 4 */
+       MATRIX_KEY(3, 6, KEY_LEFTSHIFT)         /* KEY_CAPSLOCK */
+       MATRIX_KEY(6, 1, KEY_Z)
+       MATRIX_KEY(7, 4, KEY_X)
+       MATRIX_KEY(5, 1, KEY_C)
+       MATRIX_KEY(1, 7, KEY_V)
+       MATRIX_KEY(2, 4, KEY_B)
+       MATRIX_KEY(4, 1, KEY_N)
+       MATRIX_KEY(1, 1, KEY_M)
+       MATRIX_KEY(3, 5, KEY_COMMA)
+       MATRIX_KEY(5, 2, KEY_DOT)
+       MATRIX_KEY(6, 3, KEY_UP)
+       MATRIX_KEY(7, 3, KEY_OK)
+
+       /* Row 5 */
+       MATRIX_KEY(2, 5, KEY_LEFTCTRL)          /* KEY_LEFTSHIFT */
+       MATRIX_KEY(4, 5, KEY_LEFTALT)           /* SYM */
+       MATRIX_KEY(6, 0, KEY_MINUS)
+       MATRIX_KEY(4, 7, KEY_EQUAL)
+       MATRIX_KEY(1, 5, KEY_SPACE)
+       MATRIX_KEY(3, 2, KEY_SLASH)
+       MATRIX_KEY(4, 3, KEY_LEFT)
+       MATRIX_KEY(5, 3, KEY_DOWN)
+       MATRIX_KEY(3, 3, KEY_RIGHT)
+
+       /* Side buttons, KEY_VOLUMEDOWN and KEY_PWER are on CPCAP? */
+       MATRIX_KEY(5, 0, KEY_VOLUMEUP)
+       >;
+};
+
+&mmc1 {
+       vmmc-supply = <&vwlan2>;
+       bus-width = <4>;
+       cd-gpios = <&gpio6 16 GPIO_ACTIVE_LOW>; /* gpio176 */
+};
+
+&mmc2 {
+       vmmc-supply = <&vsdio>;
+       bus-width = <8>;
+       ti,non-removable;
+};
+
+&mmc3 {
+       vmmc-supply = <&wl12xx_vmmc>;
+       /* uart2_tx.sdmmc3_dat1 pad as wakeirq */
+       interrupts-extended = <&wakeupgen GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH
+                              &omap4_pmx_core 0xde>;
+       interrupt-names = "irq", "wakeup";
+       non-removable;
+       bus-width = <4>;
+       cap-power-off-card;
+       keep-power-in-suspend;
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+       wlcore: wlcore@2 {
+               compatible = "ti,wl1285", "ti,wl1283";
+               reg = <2>;
+               /* gpio_100 with gpmc_wait2 pad as wakeirq */
+               interrupts-extended = <&gpio4 4 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&omap4_pmx_core 0x4e>;
+               interrupt-names = "irq", "wakeup";
+               ref-clock-frequency = <26000000>;
+               tcxo-clock-frequency = <26000000>;
+       };
+};
+
+&i2c1 {
+       led-controller@38 {
+               compatible = "ti,lm3532";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x38>;
+
+               enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+
+               ramp-up-us = <1024>;
+               ramp-down-us = <8193>;
+
+               led@0 {
+                       reg = <0>;
+                       led-sources = <2>;
+                       ti,led-mode = <0>;
+                       label = ":backlight";
+                       linux,default-trigger = "backlight";
+               };
+
+               led@1 {
+                       reg = <1>;
+                       led-sources = <1>;
+                       ti,led-mode = <0>;
+                       label = ":kbd_backlight";
+               };
+       };
+};
+
+&i2c2 {
+       touchscreen@4a {
+               compatible = "atmel,maxtouch";
+               reg = <0x4a>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&touchscreen_pins>;
+
+               reset-gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; /* gpio173 */
+
+               /* gpio_183 with sys_nirq2 pad as wakeup */
+               interrupts-extended = <&gpio6 23 IRQ_TYPE_EDGE_FALLING>,
+                                     <&omap4_pmx_core 0x160>;
+               interrupt-names = "irq", "wakeup";
+               wakeup-source;
+       };
+
+       isl29030@44 {
+               compatible = "isil,isl29030";
+               reg = <0x44>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&als_proximity_pins>;
+
+               interrupt-parent = <&gpio6>;
+               interrupts = <17 IRQ_TYPE_LEVEL_LOW>; /* gpio177 */
+       };
+};
+
+&omap4_pmx_core {
+
+       /* hdmi_hpd.gpio_63 */
+       hdmi_hpd_gpio: pinmux_hdmi_hpd_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3)
+               >;
+       };
+
+       /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */
+       dss_hdmi_pins: pinmux_dss_hdmi_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0)
+               OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0)
+               OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0)
+               >;
+       };
+
+       /* gpmc_ncs0.gpio_50 */
+       poweroff_gpio: pinmux_poweroff_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x074, PIN_OUTPUT_PULLUP | MUX_MODE3)
+               >;
+       };
+
+       /* kpd_row0.gpio_178 */
+       tmp105_irq: pinmux_tmp105_irq {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x18e, PIN_INPUT_PULLUP | MUX_MODE3)
+               >;
+       };
+
+       usb_gpio_mux_sel1: pinmux_usb_gpio_mux_sel1_pins {
+               /* gpio_60 */
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3)
+               >;
+       };
+
+       touchscreen_pins: pinmux_touchscreen_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3)
+               OMAP4_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE3)
+               >;
+       };
+
+       als_proximity_pins: pinmux_als_proximity_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x18c, PIN_INPUT_PULLUP | MUX_MODE3)
+               >;
+       };
+
+       usb_mdm6600_pins: pinmux_usb_mdm6600_pins {
+               pinctrl-single,pins = <
+               /* enable 0x4a1000d8 usbb1_ulpitll_dat7.gpio_95 ag16 */
+               OMAP4_IOPAD(0x0d8, PIN_INPUT | MUX_MODE3)
+
+               /* power 0x4a10007c gpmc_nwp.gpio_54 c25 */
+               OMAP4_IOPAD(0x07c, PIN_OUTPUT | MUX_MODE3)
+
+               /* reset 0x4a100072 gpmc_a25.gpio_49 d20 */
+               OMAP4_IOPAD(0x072, PIN_OUTPUT | MUX_MODE3)
+
+               /* mode0/bpwake 0x4a10014e sdmmc5_dat1.gpio_148 af4 */
+               OMAP4_IOPAD(0x14e, PIN_OUTPUT | MUX_MODE3)
+
+               /* mode1/apwake 0x4a100150 sdmmc5_dat2.gpio_149 ag3 */
+               OMAP4_IOPAD(0x150, PIN_OFF_OUTPUT_LOW | PIN_INPUT | MUX_MODE3)
+
+               /* status0 0x4a10007e gpmc_clk.gpio_55 b22 */
+               OMAP4_IOPAD(0x07e, PIN_INPUT | MUX_MODE3)
+
+               /* status1 0x4a10007a gpmc_ncs3.gpio_53 c22 */
+               OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3)
+
+               /* status2 0x4a100078 gpmc_ncs2.gpio_52 d21 */
+               OMAP4_IOPAD(0x078, PIN_INPUT | MUX_MODE3)
+
+               /* cmd0 0x4a100094 gpmc_ncs6.gpio_103 c24 */
+               OMAP4_IOPAD(0x094, PIN_OUTPUT | MUX_MODE3)
+
+               /* cmd1 0x4a100096 gpmc_ncs7.gpio_104 d24 */
+               OMAP4_IOPAD(0x096, PIN_OUTPUT | MUX_MODE3)
+
+               /* cmd2 0x4a100142 uart3_rts_sd.gpio_142 f28 */
+               OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE3)
+               >;
+       };
+
+       usb_ulpi_pins: pinmux_usb_ulpi_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x196, MUX_MODE7)
+               OMAP4_IOPAD(0x198, MUX_MODE7)
+               OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1ba, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1bc, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE0)
+               OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE0)
+               >;
+       };
+
+       /* usb0_otg_dp and usb0_otg_dm */
+       usb_utmi_pins: pinmux_usb_utmi_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x196, PIN_INPUT | MUX_MODE0)
+               OMAP4_IOPAD(0x198, PIN_INPUT | MUX_MODE0)
+               OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1ba, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1bc, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7)
+               >;
+       };
+
+       /*
+        * Note that the v3.0.8 stock userspace dynamically remuxes uart1
+        * rts pin probably for PM purposes to PIN_INPUT_PULLUP | MUX_MODE7
+        * when not used. If needed, we can add rts pin remux later based
+        * on power measurements.
+        */
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+               /* 0x4a10013c mcspi1_cs2.uart1_cts ag23 */
+               OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1)
+
+               /* 0x4a10013e mcspi1_cs3.uart1_rts ah23 */
+               OMAP4_IOPAD(0x13e, MUX_MODE1)
+
+               /* 0x4a100140 uart3_cts_rctx.uart1_tx f27 */
+               OMAP4_IOPAD(0x140, PIN_OUTPUT | MUX_MODE1)
+
+               /* 0x4a1001ca dpm_emu14.uart1_rx aa3 */
+               OMAP4_IOPAD(0x1ca, PIN_INPUT_PULLUP | MUX_MODE2)
+               >;
+       };
+
+       /* uart3_tx_irtx and uart3_rx_irrx */
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x196, MUX_MODE7)
+               OMAP4_IOPAD(0x198, MUX_MODE7)
+               OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1ba, MUX_MODE2)
+               OMAP4_IOPAD(0x1bc, PIN_INPUT | MUX_MODE2)
+               OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE7)
+               OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7)
+               >;
+       };
+
+       uart4_pins: pinmux_uart4_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0)               /* uart4_rx */
+               OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0)              /* uart4_tx */
+               OMAP4_IOPAD(0x110, PIN_INPUT_PULLUP | MUX_MODE5)        /* uart4_cts */
+               OMAP4_IOPAD(0x112, PIN_OUTPUT_PULLUP | MUX_MODE5)       /* uart4_rts */
+               >;
+       };
+
+       mcbsp2_pins: pinmux_mcbsp2_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0)       /* abe_mcbsp2_clkx */
+               OMAP4_IOPAD(0x0f8, PIN_INPUT | MUX_MODE0)       /* abe_mcbsp2_dr */
+               OMAP4_IOPAD(0x0fa, PIN_OUTPUT | MUX_MODE0)      /* abe_mcbsp2_dx */
+               OMAP4_IOPAD(0x0fc, PIN_INPUT | MUX_MODE0)       /* abe_mcbsp2_fsx */
+               >;
+       };
+
+       mcbsp3_pins: pinmux_mcbsp3_pins {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x106, PIN_INPUT | MUX_MODE1)       /* abe_mcbsp3_dr */
+               OMAP4_IOPAD(0x108, PIN_OUTPUT | MUX_MODE1)      /* abe_mcbsp3_dx */
+               OMAP4_IOPAD(0x10a, PIN_INPUT | MUX_MODE1)       /* abe_mcbsp3_clkx */
+               OMAP4_IOPAD(0x10c, PIN_INPUT | MUX_MODE1)       /* abe_mcbsp3_fsx */
+               >;
+       };
+
+       vibrator_direction_pin: pinmux_vibrator_direction_pin {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE1)      /* dmtimer8_pwm_evt (gpio_27) */
+               >;
+       };
+
+       vibrator_enable_pin: pinmux_vibrator_enable_pin {
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1)      /* dmtimer9_pwm_evt (gpio_28) */
+               >;
+       };
+};
+
+&omap4_pmx_wkup {
+       usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
+               /* gpio_wk0 */
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
+               >;
+       };
+};
+
+/* Configure pwm clock source for timers 8 & 9 */
+&timer8 {
+       assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>;
+       assigned-clock-parents = <&sys_clkin_ck>;
+};
+
+&timer9 {
+       assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>;
+       assigned-clock-parents = <&sys_clkin_ck>;
+};
+
+/*
+ * As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for
+ * uart1 wakeirq.
+ */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+       interrupts-extended = <&wakeupgen GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH
+                              &omap4_pmx_core 0xfc>;
+};
+
+&uart3 {
+       interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
+                              &omap4_pmx_core 0x17c>;
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart4_pins>;
+
+       bluetooth {
+               compatible = "ti,wl1285-st";
+               enable-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; /* gpio 174 */
+               max-speed = <3686400>;
+       };
+};
+
+&usbhsohci {
+       phys = <&fsusb1_phy>;
+       phy-names = "usb";
+};
+
+&usbhsehci {
+       phys = <&hsusb2_phy>;
+};
+
+&usbhshost {
+       port1-mode = "ohci-phy-4pin-dpdm";
+       port2-mode = "ehci-tll";
+};
+
+/* Internal UTMI+ PHY used for OTG, CPCAP ULPI PHY for detection and charger */
+&usb_otg_hs {
+       interface-type = <1>;
+       mode = <3>;
+
+       /*
+        * Max 300 mA steps based on similar PMIC MC13783UG.pdf "Table 10-4.
+        * VBUS Regulator Main Characteristics". Binding uses 2 mA units.
+        */
+       power = <150>;
+};
+
+&i2c4 {
+       ak8975: magnetometer@c {
+               compatible = "asahi-kasei,ak8975";
+               reg = <0x0c>;
+
+               vdd-supply = <&vhvio>;
+
+               interrupt-parent = <&gpio6>;
+               interrupts = <15 IRQ_TYPE_EDGE_RISING>; /* gpio175 */
+
+               rotation-matrix = "-1", "0", "0",
+                                 "0", "1", "0",
+                                 "0", "0", "-1";
+
+       };
+
+       lis3dh: accelerometer@18 {
+               compatible = "st,lis3dh-accel";
+               reg = <0x18>;
+
+               vdd-supply = <&vhvio>;
+
+               interrupt-parent = <&gpio2>;
+               interrupts = <2 IRQ_TYPE_EDGE_BOTH>; /* gpio34 */
+
+               rotation-matrix = "0", "-1", "0",
+                                 "1", "0", "0",
+                                 "0", "0", "1";
+       };
+};
+
+&mcbsp2 {
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp2_pins>;
+       status = "okay";
+
+       mcbsp2_port: port {
+               cpu_dai2: endpoint {
+                       dai-format = "i2s";
+                       remote-endpoint = <&cpcap_audio_codec0>;
+                       frame-master = <&cpcap_audio_codec0>;
+                       bitclock-master = <&cpcap_audio_codec0>;
+               };
+       };
+};
+
+&mcbsp3 {
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp3_pins>;
+       status = "okay";
+
+       mcbsp3_port: port {
+               cpu_dai3: endpoint {
+                       dai-format = "dsp_a";
+                       frame-master = <&cpcap_audio_codec1>;
+                       bitclock-master = <&cpcap_audio_codec1>;
+                       remote-endpoint = <&cpcap_audio_codec1>;
+               };
+       };
+};
+
+&cpcap_audio_codec0 {
+       remote-endpoint = <&cpu_dai2>;
+};
+
+&cpcap_audio_codec1 {
+       remote-endpoint = <&cpu_dai3>;
+};
index ba39740..7fda40a 100644 (file)
                                regulator-enable-ramp-delay = <216>;
                        };
                };
+
+               mt6323keys: mt6323keys {
+                       compatible = "mediatek,mt6323-keys";
+                       mediatek,long-press-mode = <1>;
+                       power-off-time-sec = <0>;
+
+                       power {
+                               linux,keycodes = <116>;
+                               wakeup-source;
+                       };
+
+                       home {
+                               linux,keycodes = <114>;
+                       };
+               };
+
+               codec: mt6397codec {
+                       compatible = "mediatek,mt6397-codec";
+               };
+
+               power-controller {
+                       compatible = "mediatek,mt6323-pwrc";
+               };
+
+               rtc {
+                       compatible = "mediatek,mt6323-rtc";
+               };
        };
 };
index d134ce1..5672325 100644 (file)
                interrupts = <17 IRQ_TYPE_EDGE_RISING>; /* gpio 177 */
        };
 };
+
+&uart2 {
+       bluetooth {
+               compatible = "ti,wl1835-st";
+               enable-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; /* gpio 137 */
+               max-speed = <300000>;
+       };
+};
index 9ca1d0f..df6ba12 100644 (file)
                interrupts = <8 IRQ_TYPE_EDGE_RISING>; /* gpio 136 */
        };
 };
+
+&uart2 {
+       bluetooth {
+               compatible = "ti,wl1835-st";
+               enable-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; /* gpio 137 */
+               max-speed = <300000>;
+       };
+};
index 6365988..a638e05 100644 (file)
        };
 };
 
+/* RNG not directly accessible on n900, see omap3-rom-rng instead */
+&rng_target {
+       status = "disabled";
+};
+
 &usb_otg_hs {
        interface-type = <0>;
        usb-phy = <&usb2_phy>;
index a7a04d7..f24e232 100644 (file)
        pinctrl-0 = <&mmc1_pins>;
        vmmc-supply = <&vmmc1>;
        vqmmc-supply = <&vsim>;
-       cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>;
+       cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
        bus-width = <8>;
 };
 
index 4043ecb..5698a3e 100644 (file)
@@ -8,6 +8,7 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/bus/ti-sysc.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/omap.h>
                        status = "disabled";
                };
 
+               /* Likely needs to be tagged disabled on HS devices */
+               rng_target: target-module@480a0000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x480a003c 0x4>,
+                             <0x480a0040 0x4>,
+                             <0x480a0044 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>;
+                       ti,syss-mask = <1>;
+                       clocks = <&rng_ick>;
+                       clock-names = "ick";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x480a0000 0x2000>;
+
+                       rng: rng@0 {
+                               compatible = "ti,omap2-rng";
+                               reg = <0x0 0x2000>;
+                               interrupts = <52>;
+                       };
+               };
+
                mcbsp2: mcbsp@49022000 {
                        compatible = "ti,omap3-mcbsp";
                        reg = <0x49022000 0xff>,
index 5e9d1af..21079cd 100644 (file)
                         <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
                         <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>, <&icr_ick>,
                         <&des2_ick>, <&mspro_ick>, <&mailboxes_ick>,
-                        <&mspro_fck>;
+                        <&rng_ick>, <&mspro_fck>;
        };
 };
diff --git a/arch/arm/boot/dts/omap4-droid-bionic-xt875.dts b/arch/arm/boot/dts/omap4-droid-bionic-xt875.dts
new file mode 100644 (file)
index 0000000..ba5c35b
--- /dev/null
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/dts-v1/;
+
+#include "motorola-mapphone-common.dtsi"
+
+/ {
+       model = "Motorola Droid Bionic XT875";
+       compatible = "motorola,droid-bionic", "ti,omap4430", "ti,omap4";
+};
index a40fe8d..c0d2fd9 100644 (file)
@@ -1,784 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /dts-v1/;
 
-#include <dt-bindings/input/input.h>
-#include "omap443x.dtsi"
-#include "motorola-cpcap-mapphone.dtsi"
+#include "motorola-mapphone-common.dtsi"
 
 / {
        model = "Motorola Droid 4 XT894";
        compatible = "motorola,droid4", "ti,omap4430", "ti,omap4";
-
-       chosen {
-               stdout-path = &uart3;
-       };
-
-       aliases {
-               display0 = &lcd0;
-               display1 = &hdmi0;
-       };
-
-       /*
-        * We seem to have only 1021 MB accessible, 1021 - 1022 is locked,
-        * then 1023 - 1024 seems to contain mbm.
-        */
-       memory {
-               device_type = "memory";
-               reg = <0x80000000 0x3fd00000>;  /* 1021 MB */
-       };
-
-       /* Poweroff GPIO probably connected to CPCAP */
-       gpio-poweroff {
-               compatible = "gpio-poweroff";
-               pinctrl-0 = <&poweroff_gpio>;
-               pinctrl-names = "default";
-               gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;    /* gpio50 */
-       };
-
-       hdmi0: connector {
-               compatible = "hdmi-connector";
-               pinctrl-0 = <&hdmi_hpd_gpio>;
-               pinctrl-names = "default";
-               label = "hdmi";
-               type = "d";
-
-               hpd-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>;       /* gpio63 */
-
-               port {
-                       hdmi_connector_in: endpoint {
-                               remote-endpoint = <&hdmi_out>;
-                       };
-               };
-       };
-
-       /*
-        * HDMI 5V regulator probably sourced from battery. Let's keep
-        * keep this as always enabled for HDMI to work until we've
-        * figured what the encoder chip is.
-        */
-       hdmi_regulator: regulator-hdmi {
-               compatible = "regulator-fixed";
-               regulator-name = "hdmi";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               gpio = <&gpio2 27 GPIO_ACTIVE_HIGH>;    /* gpio59 */
-               enable-active-high;
-               regulator-always-on;
-       };
-
-       /* FS USB Host PHY on port 1 for mdm6600 */
-       fsusb1_phy: usb-phy@1 {
-               compatible = "motorola,mapphone-mdm6600";
-               pinctrl-0 = <&usb_mdm6600_pins>;
-               pinctrl-names = "default";
-               enable-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>;     /* gpio_95 */
-               power-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>;     /* gpio_54 */
-               reset-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>;     /* gpio_49 */
-               /* mode: gpio_148 gpio_149 */
-               motorola,mode-gpios = <&gpio5 20 GPIO_ACTIVE_HIGH>,
-                                     <&gpio5 21 GPIO_ACTIVE_HIGH>;
-               /* cmd: gpio_103 gpio_104 gpio_142 */
-               motorola,cmd-gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>,
-                                    <&gpio4 8 GPIO_ACTIVE_HIGH>,
-                                    <&gpio5 14 GPIO_ACTIVE_HIGH>;
-               /* status: gpio_52 gpio_53 gpio_55 */
-               motorola,status-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>,
-                                       <&gpio2 21 GPIO_ACTIVE_HIGH>,
-                                       <&gpio2 23 GPIO_ACTIVE_HIGH>;
-               #phy-cells = <0>;
-       };
-
-       /* HS USB host TLL nop-phy on port 2 for w3glte */
-       hsusb2_phy: usb-phy@2 {
-               compatible = "usb-nop-xceiv";
-               #phy-cells = <0>;
-       };
-
-       /* LCD regulator from sw5 source */
-       lcd_regulator: regulator-lcd {
-               compatible = "regulator-fixed";
-               regulator-name = "lcd";
-               regulator-min-microvolt = <5050000>;
-               regulator-max-microvolt = <5050000>;
-               gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;     /* gpio96 */
-               enable-active-high;
-               vin-supply = <&sw5>;
-       };
-
-       /* This is probably coming straight from the battery.. */
-       wl12xx_vmmc: regulator-wl12xx {
-               compatible = "regulator-fixed";
-               regulator-name = "vwl1271";
-               regulator-min-microvolt = <1650000>;
-               regulator-max-microvolt = <1650000>;
-               gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;    /* gpio94 */
-               startup-delay-us = <70000>;
-               enable-active-high;
-       };
-
-       gpio_keys {
-               compatible = "gpio-keys";
-
-               volume_down {
-                       label = "Volume Down";
-                       gpios = <&gpio5 26 GPIO_ACTIVE_LOW>; /* gpio154 */
-                       linux,code = <KEY_VOLUMEDOWN>;
-                       linux,can-disable;
-                       /* Value above 7.95ms for no GPIO hardware debounce */
-                       debounce-interval = <10>;
-               };
-
-               slider {
-                       label = "Keypad Slide";
-                       gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */
-                       linux,input-type = <EV_SW>;
-                       linux,code = <SW_KEYPAD_SLIDE>;
-                       linux,can-disable;
-                       /* Value above 7.95ms for no GPIO hardware debounce */
-                       debounce-interval = <10>;
-               };
-       };
-
-       soundcard {
-               compatible = "audio-graph-card";
-               label = "Droid 4 Audio";
-
-               simple-graph-card,widgets =
-                       "Speaker", "Earpiece",
-                       "Speaker", "Loudspeaker",
-                       "Headphone", "Headphone Jack",
-                       "Microphone", "Internal Mic";
-
-               simple-graph-card,routing =
-                       "Earpiece", "EP",
-                       "Loudspeaker", "SPKR",
-                       "Headphone Jack", "HSL",
-                       "Headphone Jack", "HSR",
-                       "MICR", "Internal Mic";
-
-               dais = <&mcbsp2_port>, <&mcbsp3_port>;
-       };
-
-       pwm8: dmtimer-pwm-8 {
-               pinctrl-names = "default";
-               pinctrl-0 = <&vibrator_direction_pin>;
-
-               compatible = "ti,omap-dmtimer-pwm";
-               #pwm-cells = <3>;
-               ti,timers = <&timer8>;
-               ti,clock-source = <0x01>;
-       };
-
-       pwm9: dmtimer-pwm-9 {
-               pinctrl-names = "default";
-               pinctrl-0 = <&vibrator_enable_pin>;
-
-               compatible = "ti,omap-dmtimer-pwm";
-               #pwm-cells = <3>;
-               ti,timers = <&timer9>;
-               ti,clock-source = <0x01>;
-       };
-
-       vibrator {
-               compatible = "pwm-vibrator";
-               pwms = <&pwm9 0 10000000 0>, <&pwm8 0 10000000 0>;
-               pwm-names = "enable", "direction";
-               direction-duty-cycle-ns = <10000000>;
-       };
-};
-
-&dss {
-       status = "okay";
-};
-
-&dsi1 {
-       status = "okay";
-       vdd-supply = <&vcsi>;
-
-       port {
-               dsi1_out_ep: endpoint {
-                       remote-endpoint = <&lcd0_in>;
-                       lanes = <0 1 2 3 4 5>;
-               };
-       };
-
-       lcd0: display {
-               compatible = "panel-dsi-cm";
-               label = "lcd0";
-               vddi-supply = <&lcd_regulator>;
-               reset-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>;      /* gpio101 */
-
-               width-mm = <50>;
-               height-mm = <89>;
-
-               panel-timing {
-                       clock-frequency = <0>;          /* Calculated by dsi */
-
-                       hback-porch = <2>;
-                       hactive = <540>;
-                       hfront-porch = <0>;
-                       hsync-len = <2>;
-
-                       vback-porch = <1>;
-                       vactive = <960>;
-                       vfront-porch = <0>;
-                       vsync-len = <1>;
-
-                       hsync-active = <0>;
-                       vsync-active = <0>;
-                       de-active = <1>;
-                       pixelclk-active = <1>;
-               };
-
-               port {
-                       lcd0_in: endpoint {
-                               remote-endpoint = <&dsi1_out_ep>;
-                       };
-               };
-       };
-};
-
-&hdmi {
-       status = "okay";
-       pinctrl-0 = <&dss_hdmi_pins>;
-       pinctrl-names = "default";
-       vdda-supply = <&vdac>;
-
-       port {
-               hdmi_out: endpoint {
-                       remote-endpoint = <&hdmi_connector_in>;
-                       lanes = <1 0 3 2 5 4 7 6>;
-               };
-       };
-};
-
-&i2c1 {
-       tmp105@48 {
-               compatible = "ti,tmp105";
-               reg = <0x48>;
-               pinctrl-0 = <&tmp105_irq>;
-               pinctrl-names = "default";
-               /* kpd_row0.gpio_178 */
-               interrupts-extended = <&gpio6 18 IRQ_TYPE_EDGE_FALLING
-                                      &omap4_pmx_core 0x14e>;
-               interrupt-names = "irq", "wakeup";
-               wakeup-source;
-       };
-};
-
-&keypad {
-       keypad,num-rows = <8>;
-       keypad,num-columns = <8>;
-       linux,keymap = <
-
-       /* Row 1 */
-       MATRIX_KEY(0, 2, KEY_1)
-       MATRIX_KEY(0, 6, KEY_2)
-       MATRIX_KEY(2, 3, KEY_3)
-       MATRIX_KEY(0, 7, KEY_4)
-       MATRIX_KEY(0, 4, KEY_5)
-       MATRIX_KEY(5, 5, KEY_6)
-       MATRIX_KEY(0, 1, KEY_7)
-       MATRIX_KEY(0, 5, KEY_8)
-       MATRIX_KEY(0, 0, KEY_9)
-       MATRIX_KEY(1, 6, KEY_0)
-
-       /* Row 2 */
-       MATRIX_KEY(3, 4, KEY_APOSTROPHE)
-       MATRIX_KEY(7, 6, KEY_Q)
-       MATRIX_KEY(7, 7, KEY_W)
-       MATRIX_KEY(7, 2, KEY_E)
-       MATRIX_KEY(1, 0, KEY_R)
-       MATRIX_KEY(4, 4, KEY_T)
-       MATRIX_KEY(1, 2, KEY_Y)
-       MATRIX_KEY(6, 7, KEY_U)
-       MATRIX_KEY(2, 2, KEY_I)
-       MATRIX_KEY(5, 6, KEY_O)
-       MATRIX_KEY(3, 7, KEY_P)
-       MATRIX_KEY(6, 5, KEY_BACKSPACE)
-
-       /* Row 3 */
-       MATRIX_KEY(5, 4, KEY_TAB)
-       MATRIX_KEY(5, 7, KEY_A)
-       MATRIX_KEY(2, 7, KEY_S)
-       MATRIX_KEY(7, 0, KEY_D)
-       MATRIX_KEY(2, 6, KEY_F)
-       MATRIX_KEY(6, 2, KEY_G)
-       MATRIX_KEY(6, 6, KEY_H)
-       MATRIX_KEY(1, 4, KEY_J)
-       MATRIX_KEY(3, 1, KEY_K)
-       MATRIX_KEY(2, 1, KEY_L)
-       MATRIX_KEY(4, 6, KEY_ENTER)
-
-       /* Row 4 */
-       MATRIX_KEY(3, 6, KEY_LEFTSHIFT)         /* KEY_CAPSLOCK */
-       MATRIX_KEY(6, 1, KEY_Z)
-       MATRIX_KEY(7, 4, KEY_X)
-       MATRIX_KEY(5, 1, KEY_C)
-       MATRIX_KEY(1, 7, KEY_V)
-       MATRIX_KEY(2, 4, KEY_B)
-       MATRIX_KEY(4, 1, KEY_N)
-       MATRIX_KEY(1, 1, KEY_M)
-       MATRIX_KEY(3, 5, KEY_COMMA)
-       MATRIX_KEY(5, 2, KEY_DOT)
-       MATRIX_KEY(6, 3, KEY_UP)
-       MATRIX_KEY(7, 3, KEY_OK)
-
-       /* Row 5 */
-       MATRIX_KEY(2, 5, KEY_LEFTCTRL)          /* KEY_LEFTSHIFT */
-       MATRIX_KEY(4, 5, KEY_LEFTALT)           /* SYM */
-       MATRIX_KEY(6, 0, KEY_MINUS)
-       MATRIX_KEY(4, 7, KEY_EQUAL)
-       MATRIX_KEY(1, 5, KEY_SPACE)
-       MATRIX_KEY(3, 2, KEY_SLASH)
-       MATRIX_KEY(4, 3, KEY_LEFT)
-       MATRIX_KEY(5, 3, KEY_DOWN)
-       MATRIX_KEY(3, 3, KEY_RIGHT)
-
-       /* Side buttons, KEY_VOLUMEDOWN and KEY_PWER are on CPCAP? */
-       MATRIX_KEY(5, 0, KEY_VOLUMEUP)
-       >;
-};
-
-&mmc1 {
-       vmmc-supply = <&vwlan2>;
-       bus-width = <4>;
-       cd-gpios = <&gpio6 16 GPIO_ACTIVE_LOW>; /* gpio176 */
-};
-
-&mmc2 {
-       vmmc-supply = <&vsdio>;
-       bus-width = <8>;
-       ti,non-removable;
-};
-
-&mmc3 {
-       vmmc-supply = <&wl12xx_vmmc>;
-       /* uart2_tx.sdmmc3_dat1 pad as wakeirq */
-       interrupts-extended = <&wakeupgen GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH
-                              &omap4_pmx_core 0xde>;
-       interrupt-names = "irq", "wakeup";
-       non-removable;
-       bus-width = <4>;
-       cap-power-off-card;
-       keep-power-in-suspend;
-
-       #address-cells = <1>;
-       #size-cells = <0>;
-       wlcore: wlcore@2 {
-               compatible = "ti,wl1285", "ti,wl1283";
-               reg = <2>;
-               /* gpio_100 with gpmc_wait2 pad as wakeirq */
-               interrupts-extended = <&gpio4 4 IRQ_TYPE_LEVEL_HIGH>,
-                                     <&omap4_pmx_core 0x4e>;
-               interrupt-names = "irq", "wakeup";
-               ref-clock-frequency = <26000000>;
-               tcxo-clock-frequency = <26000000>;
-       };
-};
-
-&i2c1 {
-       led-controller@38 {
-               compatible = "ti,lm3532";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               reg = <0x38>;
-
-               enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
-
-               ramp-up-us = <1024>;
-               ramp-down-us = <8193>;
-
-               led@0 {
-                       reg = <0>;
-                       led-sources = <2>;
-                       ti,led-mode = <0>;
-                       label = ":backlight";
-                       linux,default-trigger = "backlight";
-               };
-
-               led@1 {
-                       reg = <1>;
-                       led-sources = <1>;
-                       ti,led-mode = <0>;
-                       label = ":kbd_backlight";
-               };
-       };
-};
-
-&i2c2 {
-       touchscreen@4a {
-               compatible = "atmel,maxtouch";
-               reg = <0x4a>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&touchscreen_pins>;
-
-               reset-gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; /* gpio173 */
-
-               /* gpio_183 with sys_nirq2 pad as wakeup */
-               interrupts-extended = <&gpio6 23 IRQ_TYPE_EDGE_FALLING>,
-                                     <&omap4_pmx_core 0x160>;
-               interrupt-names = "irq", "wakeup";
-               wakeup-source;
-       };
-
-       isl29030@44 {
-               compatible = "isil,isl29030";
-               reg = <0x44>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&als_proximity_pins>;
-
-               interrupt-parent = <&gpio6>;
-               interrupts = <17 IRQ_TYPE_LEVEL_LOW>; /* gpio177 */
-       };
-};
-
-&omap4_pmx_core {
-
-       /* hdmi_hpd.gpio_63 */
-       hdmi_hpd_gpio: pinmux_hdmi_hpd_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3)
-               >;
-       };
-
-       /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */
-       dss_hdmi_pins: pinmux_dss_hdmi_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0)
-               OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0)
-               OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0)
-               >;
-       };
-
-       /* gpmc_ncs0.gpio_50 */
-       poweroff_gpio: pinmux_poweroff_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x074, PIN_OUTPUT_PULLUP | MUX_MODE3)
-               >;
-       };
-
-       /* kpd_row0.gpio_178 */
-       tmp105_irq: pinmux_tmp105_irq {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x18e, PIN_INPUT_PULLUP | MUX_MODE3)
-               >;
-       };
-
-       usb_gpio_mux_sel1: pinmux_usb_gpio_mux_sel1_pins {
-               /* gpio_60 */
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3)
-               >;
-       };
-
-       touchscreen_pins: pinmux_touchscreen_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3)
-               OMAP4_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE3)
-               >;
-       };
-
-       als_proximity_pins: pinmux_als_proximity_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x18c, PIN_INPUT_PULLUP | MUX_MODE3)
-               >;
-       };
-
-       usb_mdm6600_pins: pinmux_usb_mdm6600_pins {
-               pinctrl-single,pins = <
-               /* enable 0x4a1000d8 usbb1_ulpitll_dat7.gpio_95 ag16 */
-               OMAP4_IOPAD(0x0d8, PIN_INPUT | MUX_MODE3)
-
-               /* power 0x4a10007c gpmc_nwp.gpio_54 c25 */
-               OMAP4_IOPAD(0x07c, PIN_OUTPUT | MUX_MODE3)
-
-               /* reset 0x4a100072 gpmc_a25.gpio_49 d20 */
-               OMAP4_IOPAD(0x072, PIN_OUTPUT | MUX_MODE3)
-
-               /* mode0/bpwake 0x4a10014e sdmmc5_dat1.gpio_148 af4 */
-               OMAP4_IOPAD(0x14e, PIN_OUTPUT | MUX_MODE3)
-
-               /* mode1/apwake 0x4a100150 sdmmc5_dat2.gpio_149 ag3 */
-               OMAP4_IOPAD(0x150, PIN_OFF_OUTPUT_LOW | PIN_INPUT | MUX_MODE3)
-
-               /* status0 0x4a10007e gpmc_clk.gpio_55 b22 */
-               OMAP4_IOPAD(0x07e, PIN_INPUT | MUX_MODE3)
-
-               /* status1 0x4a10007a gpmc_ncs3.gpio_53 c22 */
-               OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3)
-
-               /* status2 0x4a100078 gpmc_ncs2.gpio_52 d21 */
-               OMAP4_IOPAD(0x078, PIN_INPUT | MUX_MODE3)
-
-               /* cmd0 0x4a100094 gpmc_ncs6.gpio_103 c24 */
-               OMAP4_IOPAD(0x094, PIN_OUTPUT | MUX_MODE3)
-
-               /* cmd1 0x4a100096 gpmc_ncs7.gpio_104 d24 */
-               OMAP4_IOPAD(0x096, PIN_OUTPUT | MUX_MODE3)
-
-               /* cmd2 0x4a100142 uart3_rts_sd.gpio_142 f28 */
-               OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE3)
-               >;
-       };
-
-       usb_ulpi_pins: pinmux_usb_ulpi_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x196, MUX_MODE7)
-               OMAP4_IOPAD(0x198, MUX_MODE7)
-               OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1ba, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1bc, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE0)
-               OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE0)
-               >;
-       };
-
-       /* usb0_otg_dp and usb0_otg_dm */
-       usb_utmi_pins: pinmux_usb_utmi_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x196, PIN_INPUT | MUX_MODE0)
-               OMAP4_IOPAD(0x198, PIN_INPUT | MUX_MODE0)
-               OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1ba, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1bc, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7)
-               >;
-       };
-
-       /*
-        * Note that the v3.0.8 stock userspace dynamically remuxes uart1
-        * rts pin probably for PM purposes to PIN_INPUT_PULLUP | MUX_MODE7
-        * when not used. If needed, we can add rts pin remux later based
-        * on power measurements.
-        */
-       uart1_pins: pinmux_uart1_pins {
-               pinctrl-single,pins = <
-               /* 0x4a10013c mcspi1_cs2.uart1_cts ag23 */
-               OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1)
-
-               /* 0x4a10013e mcspi1_cs3.uart1_rts ah23 */
-               OMAP4_IOPAD(0x13e, MUX_MODE1)
-
-               /* 0x4a100140 uart3_cts_rctx.uart1_tx f27 */
-               OMAP4_IOPAD(0x140, PIN_OUTPUT | MUX_MODE1)
-
-               /* 0x4a1001ca dpm_emu14.uart1_rx aa3 */
-               OMAP4_IOPAD(0x1ca, PIN_INPUT_PULLUP | MUX_MODE2)
-               >;
-       };
-
-       /* uart3_tx_irtx and uart3_rx_irrx */
-       uart3_pins: pinmux_uart3_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x196, MUX_MODE7)
-               OMAP4_IOPAD(0x198, MUX_MODE7)
-               OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1ba, MUX_MODE2)
-               OMAP4_IOPAD(0x1bc, PIN_INPUT | MUX_MODE2)
-               OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE7)
-               OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7)
-               >;
-       };
-
-       uart4_pins: pinmux_uart4_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0)               /* uart4_rx */
-               OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0)              /* uart4_tx */
-               OMAP4_IOPAD(0x110, PIN_INPUT_PULLUP | MUX_MODE5)        /* uart4_cts */
-               OMAP4_IOPAD(0x112, PIN_OUTPUT_PULLUP | MUX_MODE5)       /* uart4_rts */
-               >;
-       };
-
-       mcbsp2_pins: pinmux_mcbsp2_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0)       /* abe_mcbsp2_clkx */
-               OMAP4_IOPAD(0x0f8, PIN_INPUT | MUX_MODE0)       /* abe_mcbsp2_dr */
-               OMAP4_IOPAD(0x0fa, PIN_OUTPUT | MUX_MODE0)      /* abe_mcbsp2_dx */
-               OMAP4_IOPAD(0x0fc, PIN_INPUT | MUX_MODE0)       /* abe_mcbsp2_fsx */
-               >;
-       };
-
-       mcbsp3_pins: pinmux_mcbsp3_pins {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x106, PIN_INPUT | MUX_MODE1)       /* abe_mcbsp3_dr */
-               OMAP4_IOPAD(0x108, PIN_OUTPUT | MUX_MODE1)      /* abe_mcbsp3_dx */
-               OMAP4_IOPAD(0x10a, PIN_INPUT | MUX_MODE1)       /* abe_mcbsp3_clkx */
-               OMAP4_IOPAD(0x10c, PIN_INPUT | MUX_MODE1)       /* abe_mcbsp3_fsx */
-               >;
-       };
-
-       vibrator_direction_pin: pinmux_vibrator_direction_pin {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE1)      /* dmtimer8_pwm_evt (gpio_27) */
-               >;
-       };
-
-       vibrator_enable_pin: pinmux_vibrator_enable_pin {
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1)      /* dmtimer9_pwm_evt (gpio_28) */
-               >;
-       };
-};
-
-&omap4_pmx_wkup {
-       usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
-               /* gpio_wk0 */
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
-               >;
-       };
-};
-
-/* Configure pwm clock source for timers 8 & 9 */
-&timer8 {
-       assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>;
-       assigned-clock-parents = <&sys_clkin_ck>;
-};
-
-&timer9 {
-       assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>;
-       assigned-clock-parents = <&sys_clkin_ck>;
-};
-
-/*
- * As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for
- * uart1 wakeirq.
- */
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart1_pins>;
-       interrupts-extended = <&wakeupgen GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH
-                              &omap4_pmx_core 0xfc>;
-};
-
-&uart3 {
-       interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
-                              &omap4_pmx_core 0x17c>;
-};
-
-&uart4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart4_pins>;
-
-       bluetooth {
-               compatible = "ti,wl1285-st";
-               enable-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; /* gpio 174 */
-               max-speed = <3686400>;
-       };
-};
-
-&usbhsohci {
-       phys = <&fsusb1_phy>;
-       phy-names = "usb";
-};
-
-&usbhsehci {
-       phys = <&hsusb2_phy>;
-};
-
-&usbhshost {
-       port1-mode = "ohci-phy-4pin-dpdm";
-       port2-mode = "ehci-tll";
-};
-
-/* Internal UTMI+ PHY used for OTG, CPCAP ULPI PHY for detection and charger */
-&usb_otg_hs {
-       interface-type = <1>;
-       mode = <3>;
-       power = <50>;
-};
-
-&i2c4 {
-       ak8975: magnetometer@c {
-               compatible = "asahi-kasei,ak8975";
-               reg = <0x0c>;
-
-               vdd-supply = <&vhvio>;
-
-               interrupt-parent = <&gpio6>;
-               interrupts = <15 IRQ_TYPE_EDGE_RISING>; /* gpio175 */
-
-               rotation-matrix = "-1", "0", "0",
-                                 "0", "1", "0",
-                                 "0", "0", "-1";
-
-       };
-
-       lis3dh: accelerometer@18 {
-               compatible = "st,lis3dh-accel";
-               reg = <0x18>;
-
-               vdd-supply = <&vhvio>;
-
-               interrupt-parent = <&gpio2>;
-               interrupts = <2 IRQ_TYPE_EDGE_BOTH>; /* gpio34 */
-
-               rotation-matrix = "0", "-1", "0",
-                                 "1", "0", "0",
-                                 "0", "0", "1";
-       };
-};
-
-&mcbsp2 {
-       #sound-dai-cells = <0>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&mcbsp2_pins>;
-       status = "okay";
-
-       mcbsp2_port: port {
-               cpu_dai2: endpoint {
-                       dai-format = "i2s";
-                       remote-endpoint = <&cpcap_audio_codec0>;
-                       frame-master = <&cpcap_audio_codec0>;
-                       bitclock-master = <&cpcap_audio_codec0>;
-               };
-       };
-};
-
-&mcbsp3 {
-       #sound-dai-cells = <0>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&mcbsp3_pins>;
-       status = "okay";
-
-       mcbsp3_port: port {
-               cpu_dai3: endpoint {
-                       dai-format = "dsp_a";
-                       frame-master = <&cpcap_audio_codec1>;
-                       bitclock-master = <&cpcap_audio_codec1>;
-                       remote-endpoint = <&cpcap_audio_codec1>;
-               };
-       };
-};
-
-&cpcap_audio_codec0 {
-       remote-endpoint = <&cpu_dai2>;
-};
-
-&cpcap_audio_codec1 {
-       remote-endpoint = <&cpu_dai3>;
 };
index 8e6662b..6c892fc 100644 (file)
@@ -86,7 +86,6 @@
 
                target-module@22000 {                   /* 0x40122000, ap 2 02.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mcbsp1";
                        reg = <0x2208c 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
 
                target-module@24000 {                   /* 0x40124000, ap 4 04.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mcbsp2";
                        reg = <0x2408c 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
 
                target-module@26000 {                   /* 0x40126000, ap 6 06.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mcbsp3";
                        reg = <0x2608c 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
 
                target-module@28000 {                   /* 0x40128000, ap 8 08.0 */
                        compatible = "ti,sysc-mcasp", "ti,sysc";
-                       ti,hwmods = "mcasp";
                        reg = <0x28000 0x4>,
                              <0x28004 0x4>;
                        reg-names = "rev", "sysc";
index d60d5e0..83f803b 100644 (file)
 
                target-module@2b000 {                   /* 0x4a0ab000, ap 84 12.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "usb_otg_hs";
                        reg = <0x2b400 0x4>,
                              <0x2b404 0x4>,
                              <0x2b408 0x4>;
 
                target-module@74000 {                   /* 0x4a0f4000, ap 27 24.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox";
                        reg = <0x74000 0x4>,
                              <0x74010 0x4>;
                        reg-names = "rev", "sysc";
                        ranges = <0x0 0x6000 0x2000>;
 
                        prm: prm@0 {
-                               compatible = "ti,omap4-prm";
+                               compatible = "ti,omap4-prm", "simple-bus";
                                reg = <0x0 0x2000>;
                                interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                #address-cells = <1>;
 
                gpio1_target: target-module@0 {                 /* 0x4a310000, ap 5 14.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio1";
                        reg = <0x0 0x4>,
                              <0x10 0x4>,
                              <0x114 0x4>;
 
                target-module@55000 {                   /* 0x48055000, ap 15 0c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio2";
                        reg = <0x55000 0x4>,
                              <0x55010 0x4>,
                              <0x55114 0x4>;
 
                target-module@57000 {                   /* 0x48057000, ap 17 16.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio3";
                        reg = <0x57000 0x4>,
                              <0x57010 0x4>,
                              <0x57114 0x4>;
 
                target-module@59000 {                   /* 0x48059000, ap 19 10.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio4";
                        reg = <0x59000 0x4>,
                              <0x59010 0x4>,
                              <0x59114 0x4>;
 
                target-module@5b000 {                   /* 0x4805b000, ap 21 12.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio5";
                        reg = <0x5b000 0x4>,
                              <0x5b010 0x4>,
                              <0x5b114 0x4>;
 
                target-module@5d000 {                   /* 0x4805d000, ap 23 14.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio6";
                        reg = <0x5d000 0x4>,
                              <0x5d010 0x4>,
                              <0x5d114 0x4>;
 
                target-module@96000 {                   /* 0x48096000, ap 37 26.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mcbsp4";
                        reg = <0x9608c 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
 
                target-module@98000 {                   /* 0x48098000, ap 49 22.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi1";
                        reg = <0x98000 0x4>,
                              <0x98010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@9a000 {                   /* 0x4809a000, ap 51 2c.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi2";
                        reg = <0x9a000 0x4>,
                              <0x9a010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@b2000 {                   /* 0x480b2000, ap 65 3c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "hdq1w";
                        reg = <0xb2000 0x4>,
                              <0xb2014 0x4>,
                              <0xb2018 0x4>;
 
                target-module@b8000 {                   /* 0x480b8000, ap 69 58.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi3";
                        reg = <0xb8000 0x4>,
                              <0xb8010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@ba000 {                   /* 0x480ba000, ap 71 32.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi4";
                        reg = <0xba000 0x4>,
                              <0xba010 0x4>;
                        reg-names = "rev", "sysc";
index 7cc95bc..2de8a6b 100644 (file)
                l4_abe: interconnect@40100000 {
                };
 
-               ocmcram: ocmcram@40304000 {
+               ocmcram: sram@40304000 {
                        compatible = "mmio-sram";
                        reg = <0x40304000 0xa000>; /* 40k */
                };
 
                target-module@56000000 {
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       reg = <0x5601fc00 0x4>,
-                             <0x5601fc10 0x4>;
+                       reg = <0x5600fe00 0x4>,
+                             <0x5600fe10 0x4>;
                        reg-names = "rev", "sysc";
                        ti,sysc-midle = <SYSC_IDLE_FORCE>,
                                        <SYSC_IDLE_NO>,
 #include "omap4-l4.dtsi"
 #include "omap4-l4-abe.dtsi"
 #include "omap44xx-clocks.dtsi"
+
+&prm {
+       prm_tesla: prm@400 {
+               compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst";
+               reg = <0x400 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_core: prm@700 {
+               compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst";
+               reg = <0x700 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_ivahd: prm@f00 {
+               compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst";
+               reg = <0xf00 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_device: prm@1b00 {
+               compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1b00 0x40>;
+               #reset-cells = <1>;
+       };
+};
index dc9d053..23aa907 100644 (file)
@@ -86,7 +86,6 @@
 
                target-module@22000 {                   /* 0x40122000, ap 2 02.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mcbsp1";
                        reg = <0x2208c 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
 
                target-module@24000 {                   /* 0x40124000, ap 4 04.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mcbsp2";
                        reg = <0x2408c 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
 
                target-module@26000 {                   /* 0x40126000, ap 6 06.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mcbsp3";
                        reg = <0x2608c 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
index 0960348..25aacf1 100644 (file)
 
                target-module@74000 {                   /* 0x4a0f4000, ap 25 04.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mailbox";
                        reg = <0x74000 0x4>,
                              <0x74010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@20000 {                   /* 0x48020000, ap 3 04.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart3";
                        reg = <0x20050 0x4>,
                              <0x20054 0x4>,
                              <0x20058 0x4>;
 
                target-module@51000 {                   /* 0x48051000, ap 45 2e.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio7";
                        reg = <0x51000 0x4>,
                              <0x51010 0x4>,
                              <0x51114 0x4>;
 
                target-module@53000 {                   /* 0x48053000, ap 35 36.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio8";
                        reg = <0x53000 0x4>,
                              <0x53010 0x4>,
                              <0x53114 0x4>;
 
                target-module@55000 {                   /* 0x48055000, ap 13 0e.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio2";
                        reg = <0x55000 0x4>,
                              <0x55010 0x4>,
                              <0x55114 0x4>;
 
                target-module@57000 {                   /* 0x48057000, ap 15 06.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio3";
                        reg = <0x57000 0x4>,
                              <0x57010 0x4>,
                              <0x57114 0x4>;
 
                target-module@59000 {                   /* 0x48059000, ap 17 16.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio4";
                        reg = <0x59000 0x4>,
                              <0x59010 0x4>,
                              <0x59114 0x4>;
 
                target-module@5b000 {                   /* 0x4805b000, ap 19 1e.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio5";
                        reg = <0x5b000 0x4>,
                              <0x5b010 0x4>,
                              <0x5b114 0x4>;
 
                target-module@5d000 {                   /* 0x4805d000, ap 21 26.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio6";
                        reg = <0x5d000 0x4>,
                              <0x5d010 0x4>,
                              <0x5d114 0x4>;
 
                target-module@60000 {                   /* 0x48060000, ap 23 24.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c3";
                        reg = <0x60000 0x8>,
                              <0x60010 0x8>,
                              <0x60090 0x8>;
 
                target-module@66000 {                   /* 0x48066000, ap 63 4c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart5";
                        reg = <0x66050 0x4>,
                              <0x66054 0x4>,
                              <0x66058 0x4>;
 
                target-module@68000 {                   /* 0x48068000, ap 53 54.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart6";
                        reg = <0x68050 0x4>,
                              <0x68054 0x4>,
                              <0x68058 0x4>;
 
                target-module@6a000 {                   /* 0x4806a000, ap 24 0a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart1";
                        reg = <0x6a050 0x4>,
                              <0x6a054 0x4>,
                              <0x6a058 0x4>;
 
                target-module@6c000 {                   /* 0x4806c000, ap 26 22.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart2";
                        reg = <0x6c050 0x4>,
                              <0x6c054 0x4>,
                              <0x6c058 0x4>;
 
                target-module@6e000 {                   /* 0x4806e000, ap 28 44.1 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "uart4";
                        reg = <0x6e050 0x4>,
                              <0x6e054 0x4>,
                              <0x6e058 0x4>;
 
                target-module@70000 {                   /* 0x48070000, ap 30 14.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c1";
                        reg = <0x70000 0x8>,
                              <0x70010 0x8>,
                              <0x70090 0x8>;
 
                target-module@72000 {                   /* 0x48072000, ap 32 1c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c2";
                        reg = <0x72000 0x8>,
                              <0x72010 0x8>,
                              <0x72090 0x8>;
 
                target-module@7a000 {                   /* 0x4807a000, ap 81 2c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c4";
                        reg = <0x7a000 0x8>,
                              <0x7a010 0x8>,
                              <0x7a090 0x8>;
 
                target-module@7c000 {                   /* 0x4807c000, ap 83 34.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "i2c5";
                        reg = <0x7c000 0x8>,
                              <0x7c010 0x8>,
                              <0x7c090 0x8>;
 
                target-module@98000 {                   /* 0x48098000, ap 47 08.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi1";
                        reg = <0x98000 0x4>,
                              <0x98010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@9a000 {                   /* 0x4809a000, ap 49 10.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi2";
                        reg = <0x9a000 0x4>,
                              <0x9a010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@9c000 {                   /* 0x4809c000, ap 51 3a.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mmc1";
                        reg = <0x9c000 0x4>,
                              <0x9c010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@ad000 {                   /* 0x480ad000, ap 61 20.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mmc3";
                        reg = <0xad000 0x4>,
                              <0xad010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@b4000 {                   /* 0x480b4000, ap 65 42.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mmc2";
                        reg = <0xb4000 0x4>,
                              <0xb4010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@b8000 {                   /* 0x480b8000, ap 67 32.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi3";
                        reg = <0xb8000 0x4>,
                              <0xb8010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@ba000 {                   /* 0x480ba000, ap 69 18.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcspi4";
                        reg = <0xba000 0x4>,
                              <0xba010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@d1000 {                   /* 0x480d1000, ap 71 28.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mmc4";
                        reg = <0xd1000 0x4>,
                              <0xd1010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@d5000 {                   /* 0x480d5000, ap 73 30.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mmc5";
                        reg = <0xd5000 0x4>,
                              <0xd5010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@0 {                       /* 0x4ae10000, ap 5 10.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "gpio1";
                        reg = <0x0 0x4>,
                              <0x10 0x4>,
                              <0x114 0x4>;
 
                target-module@4000 {                    /* 0x4ae14000, ap 7 14.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "wd_timer2";
                        reg = <0x4000 0x4>,
                              <0x4010 0x4>,
                              <0x4014 0x4>;
index 1fb7937..1f6ad1d 100644 (file)
                l4_abe: interconnect@40100000 {
                };
 
-               ocmcram: ocmcram@40300000 {
+               ocmcram: sram@40300000 {
                        compatible = "mmio-sram";
                        reg = <0x40300000 0x20000>; /* 128k */
                };
 
 #include "omap5-l4-abe.dtsi"
 #include "omap54xx-clocks.dtsi"
+
+&prm {
+       prm_dsp: prm@400 {
+               compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst";
+               reg = <0x400 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_core: prm@700 {
+               compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst";
+               reg = <0x700 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_iva: prm@1200 {
+               compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1200 0x100>;
+               #reset-cells = <1>;
+       };
+
+       prm_device: prm@1c00 {
+               compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst";
+               reg = <0x1c00 0x100>;
+               #reset-cells = <1>;
+       };
+};
diff --git a/arch/arm/boot/dts/openbmc-flash-layout-128.dtsi b/arch/arm/boot/dts/openbmc-flash-layout-128.dtsi
new file mode 100644 (file)
index 0000000..05101a3
--- /dev/null
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+partitions {
+       compatible = "fixed-partitions";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       u-boot@0 {
+               reg = <0x0 0xe0000>; // 896KB
+               label = "u-boot";
+       };
+
+       u-boot-env@e0000 {
+               reg = <0xe0000 0x20000>; // 128KB
+               label = "u-boot-env";
+       };
+
+       kernel@100000 {
+               reg = <0x100000 0x900000>; // 9MB
+               label = "kernel";
+       };
+
+       rofs@a00000 {
+               reg = <0xa00000 0x5600000>; // 86MB
+               label = "rofs";
+       };
+
+       rwfs@6000000 {
+               reg = <0x6000000 0x2000000>; // 32MB
+               label = "rwfs";
+       };
+};
index 56f5159..8ef26da 100644 (file)
                        interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               sdhci: sdhci@7824900 {
+                       compatible = "qcom,sdhci-msm-v4";
+                       reg = <0x7824900 0x11c>, <0x7824000 0x800>;
+                       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "hc_irq", "pwr_irq";
+                       bus-width = <8>;
+                       clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>,
+                                <&gcc GCC_DCD_XO_CLK>;
+                       clock-names = "core", "iface", "xo";
+                       status = "disabled";
+               };
+
                blsp_dma: dma@7884000 {
                        compatible = "qcom,bam-v1.7.0";
                        reg = <0x07884000 0x23000>;
index bf402ae..2616039 100644 (file)
                                                regulator-max-microvolt = <2950000>;
 
                                                regulator-boot-on;
+                                               regulator-system-load = <200000>;
+                                               regulator-allow-set-load;
                                        };
 
                                        l21 {
                        };
                };
 
-               sdhc2_cd_pin_a: sdhc2-cd-pin-active {
-                       pins = "gpio62";
-                       function = "gpio";
-
-                       drive-strength = <2>;
-                       bias-disable;
-               };
-
                sdhc2_pin_a: sdhc2-pin-active {
                        clk {
                                pins = "sdc2_clk";
                bus-width = <4>;
 
                pinctrl-names = "default";
-               pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+               pinctrl-0 = <&sdhc2_pin_a>;
        };
 
        usb@f9a55000 {
                        };
                };
        };
+
+       imem@fe805000 {
+               status = "okay";
+
+               reboot-mode {
+                       mode-normal     = <0x77665501>;
+                       mode-bootloader = <0x77665500>;
+                       mode-recovery   = <0x77665502>;
+               };
+       };
 };
 
 &spmi_bus {
index 369e58f..9a84eb0 100644 (file)
                                };
                        };
                };
+
+               q6-dsp-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens 1>;
+
+                       trips {
+                               q6_dsp_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               modemtx-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens 2>;
+
+                       trips {
+                               modemtx_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               video-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens 3>;
+
+                       trips {
+                               video_alert0: trip-point0 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               wlan-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens 4>;
+
+                       trips {
+                               wlan_alert0: trip-point0 {
+                                       temperature = <105000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               gpu-thermal-top {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens 9>;
+
+                       trips {
+                               gpu1_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               gpu-thermal-bottom {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens 10>;
+
+                       trips {
+                               gpu2_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
        };
 
        cpu-pmu {
                        nvmem-cells = <&tsens_calib>, <&tsens_backup>;
                        nvmem-cell-names = "calib", "calib_backup";
                        #qcom,sensors = <11>;
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
                                clock-names = "iface";
                        };
                };
+
+               imem@fe805000 {
+                       status = "disabled";
+                       compatible = "syscon", "simple-mfd";
+                       reg = <0xfe805000 0x1000>;
+
+                       reboot-mode {
+                               compatible = "syscon-reboot-mode";
+                               offset = <0x65c>;
+                       };
+               };
        };
 
        smd {
index f198480..c1f2012 100644 (file)
                                qcom,vs-soft-start-strength = <0>;
                                regulator-initial-mode = <1>;
                        };
+
+                       pm8941_5vs2: 5vs2 {
+                               regulator-enable-ramp-delay = <1000>;
+                               regulator-pull-down;
+                               regulator-over-current-protection;
+                               qcom,ocp-max-retries = <10>;
+                               qcom,ocp-retry-delay = <30>;
+                               qcom,vs-soft-start-strength = <0>;
+                               regulator-initial-mode = <1>;
+                       };
                };
        };
 };
index 83cc619..6ec2cf7 100644 (file)
                #size-cells = <0>;
        };
 
-        /*
-         * IIC2 and I2C2 may be switched using pinmux.
-         * A fallback to GPIO is also provided.
-         */
+       /*
+        * IIC2 and I2C2 may be switched using pinmux.
+        * A fallback to GPIO is also provided.
+        */
        i2chdmi: i2c-12 {
                compatible = "i2c-demux-pinctrl";
                i2c-parent = <&iic2>, <&i2c2>, <&gpioi2c2>;
index 42f3313..48fbeb6 100644 (file)
                compatible = "gpio-keys";
 
                key-1 {
-                       gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_1>;
-                       label = "SW2-1";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_1>;
+                       label = "SW2-1";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-2 {
-                       gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_2>;
-                       label = "SW2-2";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_2>;
+                       label = "SW2-2";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-3 {
-                       gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_3>;
-                       label = "SW2-3";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_3>;
+                       label = "SW2-3";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-4 {
-                       gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_4>;
-                       label = "SW2-4";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_4>;
+                       label = "SW2-4";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-a {
-                       gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_A>;
-                       label = "SW30";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_A>;
+                       label = "SW30";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-b {
-                       gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_B>;
-                       label = "SW31";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_B>;
+                       label = "SW31";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-c {
-                       gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_C>;
-                       label = "SW32";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_C>;
+                       label = "SW32";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-d {
-                       gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_D>;
-                       label = "SW33";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_D>;
+                       label = "SW33";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-e {
-                       gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_E>;
-                       label = "SW34";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_E>;
+                       label = "SW34";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-f {
-                       gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_F>;
-                       label = "SW35";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_F>;
+                       label = "SW35";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
                key-g {
-                       gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_G>;
-                       label = "SW36";
-                       wakeup-source;
-                       debounce-interval = <20>;
+                       gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_G>;
+                       label = "SW36";
+                       wakeup-source;
+                       debounce-interval = <20>;
                };
        };
 
index 19cde89..f30d6ec 100644 (file)
                ranges;
        };
 
+       modem@10000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x10000000 0xfffffff>;
+
+               gpioc@1a08000 {
+                       compatible = "rda,8810pl-gpio";
+                       reg = <0x1a08000 0x1000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       ngpios = <32>;
+               };
+       };
+
        apb@20800000 {
                compatible = "simple-bus";
                #address-cells = <1>;
                                     <17 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "hwtimer", "ostimer";
                };
+
+               gpioa@30000 {
+                       compatible = "rda,8810pl-gpio";
+                       reg = <0x30000 0x1000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       ngpios = <32>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               gpiob@31000 {
+                       compatible = "rda,8810pl-gpio";
+                       reg = <0x31000 0x1000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       ngpios = <32>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               gpiod@32000 {
+                       compatible = "rda,8810pl-gpio";
+                       reg = <0x32000 0x1000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       ngpios = <32>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
+               };
        };
 
        apb@20a00000 {
index c776321..c70182c 100644 (file)
 
                hdmi {
                        hdmi_ctl: hdmi-ctl {
-                               rockchip,pins = <1 RK_PB0  1 &pcfg_pull_none>,
-                                               <1 RK_PB1  1 &pcfg_pull_none>,
+                               rockchip,pins = <1 RK_PB0 1 &pcfg_pull_none>,
+                                               <1 RK_PB1 1 &pcfg_pull_none>,
                                                <1 RK_PB2 1 &pcfg_pull_none>,
                                                <1 RK_PB3 1 &pcfg_pull_none>;
                        };
index 9f9e2bf..44bb5e6 100644 (file)
        };
 
        emmc {
-                       emmc_reset: emmc-reset {
-                               rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
-                       };
+               emmc_reset: emmc-reset {
+                       rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
        };
 
        gmac {
                phy_rst: phy-rst {
-                       rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO  &pcfg_output_high>;
+                       rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_output_high>;
                };
        };
 };
index 81e4e95..0aeef23 100644 (file)
 
        pmic {
                pmic_int: pmic-int {
-                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO \
-                                       &pcfg_pull_up>;
+                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
                };
 
                dvs_1: dvs-1 {
-                       rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO \
-                                       &pcfg_pull_down>;
+                       rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_down>;
                };
 
                dvs_2: dvs-2 {
-                       rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO \
-                                       &pcfg_pull_down>;
+                       rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
                };
        };
 
                };
 
                sdmmc_clk: sdmmc-clk {
-                       rockchip,pins = <6 RK_PC4 1 \
-                                       &pcfg_pull_none_drv_8ma>;
+                       rockchip,pins = <6 RK_PC4 1 &pcfg_pull_none_drv_8ma>;
                };
 
                sdmmc_cmd: sdmmc-cmd {
        sdio {
                wifi_enable: wifi-enable {
                        rockchip,pins = <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>,
-                               <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+                                       <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
 };
index 445270a..51208d1 100644 (file)
@@ -17,6 +17,7 @@
                rockchip,hp-det-gpios = <&gpio6 RK_PA5 GPIO_ACTIVE_HIGH>;
                rockchip,mic-det-gpios = <&gpio6 RK_PB3 GPIO_ACTIVE_LOW>;
                rockchip,headset-codec = <&headsetcodec>;
+               rockchip,hdmi-codec = <&hdmi>;
        };
 };
 
index b12e061..300a7e3 100644 (file)
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               brightness-levels = <
-                         0   1   2   3   4   5   6   7
-                         8   9  10  11  12  13  14  15
-                        16  17  18  19  20  21  22  23
-                        24  25  26  27  28  29  30  31
-                        32  33  34  35  36  37  38  39
-                        40  41  42  43  44  45  46  47
-                        48  49  50  51  52  53  54  55
-                        56  57  58  59  60  61  62  63
-                        64  65  66  67  68  69  70  71
-                        72  73  74  75  76  77  78  79
-                        80  81  82  83  84  85  86  87
-                        88  89  90  91  92  93  94  95
-                        96  97  98  99 100 101 102 103
-                       104 105 106 107 108 109 110 111
-                       112 113 114 115 116 117 118 119
-                       120 121 122 123 124 125 126 127
-                       128 129 130 131 132 133 134 135
-                       136 137 138 139 140 141 142 143
-                       144 145 146 147 148 149 150 151
-                       152 153 154 155 156 157 158 159
-                       160 161 162 163 164 165 166 167
-                       168 169 170 171 172 173 174 175
-                       176 177 178 179 180 181 182 183
-                       184 185 186 187 188 189 190 191
-                       192 193 194 195 196 197 198 199
-                       200 201 202 203 204 205 206 207
-                       208 209 210 211 212 213 214 215
-                       216 217 218 219 220 221 222 223
-                       224 225 226 227 228 229 230 231
-                       232 233 234 235 236 237 238 239
-                       240 241 242 243 244 245 246 247
-                       248 249 250 251 252 253 254 255>;
+               brightness-levels = <0 255>;
+               num-interpolated-steps = <255>;
                default-brightness-level = <128>;
                enable-gpios = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
index 8038620..a4966e5 100644 (file)
 
 &backlight {
        /* Jaq panel PWM must be >= 3%, so start non-zero brightness at 8 */
-       brightness-levels = <
-                 0
-                 8   9  10  11  12  13  14  15
-                16  17  18  19  20  21  22  23
-                24  25  26  27  28  29  30  31
-                32  33  34  35  36  37  38  39
-                40  41  42  43  44  45  46  47
-                48  49  50  51  52  53  54  55
-                56  57  58  59  60  61  62  63
-                64  65  66  67  68  69  70  71
-                72  73  74  75  76  77  78  79
-                80  81  82  83  84  85  86  87
-                88  89  90  91  92  93  94  95
-                96  97  98  99 100 101 102 103
-               104 105 106 107 108 109 110 111
-               112 113 114 115 116 117 118 119
-               120 121 122 123 124 125 126 127
-               128 129 130 131 132 133 134 135
-               136 137 138 139 140 141 142 143
-               144 145 146 147 148 149 150 151
-               152 153 154 155 156 157 158 159
-               160 161 162 163 164 165 166 167
-               168 169 170 171 172 173 174 175
-               176 177 178 179 180 181 182 183
-               184 185 186 187 188 189 190 191
-               192 193 194 195 196 197 198 199
-               200 201 202 203 204 205 206 207
-               208 209 210 211 212 213 214 215
-               216 217 218 219 220 221 222 223
-               224 225 226 227 228 229 230 231
-               232 233 234 235 236 237 238 239
-               240 241 242 243 244 245 246 247
-               248 249 250 251 252 253 254 255>;
+       brightness-levels = <0 8 255>;
+       num-interpolated-steps = <247>;
 };
 
 &rk808 {
index aa352d4..06a6a95 100644 (file)
                regulator-boot-on;
                vin-supply = <&vcc33_sys>;
        };
+
+       sound {
+               compatible = "rockchip,rockchip-audio-max98090";
+               rockchip,model = "VEYRON-HDMI";
+               rockchip,hdmi-codec = <&hdmi>;
+               rockchip,i2s-controller = <&i2s>;
+       };
 };
 
 &cpu_thermal {
index 55955b0..c833716 100644 (file)
 
 &backlight {
        /* Minnie panel PWM must be >= 1%, so start non-zero brightness at 3 */
-       brightness-levels = <
-                         0   3   4   5   6   7
-                         8   9  10  11  12  13  14  15
-                        16  17  18  19  20  21  22  23
-                        24  25  26  27  28  29  30  31
-                        32  33  34  35  36  37  38  39
-                        40  41  42  43  44  45  46  47
-                        48  49  50  51  52  53  54  55
-                        56  57  58  59  60  61  62  63
-                        64  65  66  67  68  69  70  71
-                        72  73  74  75  76  77  78  79
-                        80  81  82  83  84  85  86  87
-                        88  89  90  91  92  93  94  95
-                        96  97  98  99 100 101 102 103
-                       104 105 106 107 108 109 110 111
-                       112 113 114 115 116 117 118 119
-                       120 121 122 123 124 125 126 127
-                       128 129 130 131 132 133 134 135
-                       136 137 138 139 140 141 142 143
-                       144 145 146 147 148 149 150 151
-                       152 153 154 155 156 157 158 159
-                       160 161 162 163 164 165 166 167
-                       168 169 170 171 172 173 174 175
-                       176 177 178 179 180 181 182 183
-                       184 185 186 187 188 189 190 191
-                       192 193 194 195 196 197 198 199
-                       200 201 202 203 204 205 206 207
-                       208 209 210 211 212 213 214 215
-                       216 217 218 219 220 221 222 223
-                       224 225 226 227 228 229 230 231
-                       232 233 234 235 236 237 238 239
-                       240 241 242 243 244 245 246 247
-                       248 249 250 251 252 253 254 255>;
+       brightness-levels = <0 3 255>;
+       num-interpolated-steps = <252>;
 };
 
 &i2c_tunnel {
index 2755720..bebb230 100644 (file)
 
 &backlight {
        /* Tiger panel PWM must be >= 1%, so start non-zero brightness at 3 */
-       brightness-levels = <
-                 0   3   4   5   6   7
-                 8   9  10  11  12  13  14  15
-                16  17  18  19  20  21  22  23
-                24  25  26  27  28  29  30  31
-                32  33  34  35  36  37  38  39
-                40  41  42  43  44  45  46  47
-                48  49  50  51  52  53  54  55
-                56  57  58  59  60  61  62  63
-                64  65  66  67  68  69  70  71
-                72  73  74  75  76  77  78  79
-                80  81  82  83  84  85  86  87
-                88  89  90  91  92  93  94  95
-                96  97  98  99 100 101 102 103
-               104 105 106 107 108 109 110 111
-               112 113 114 115 116 117 118 119
-               120 121 122 123 124 125 126 127
-               128 129 130 131 132 133 134 135
-               136 137 138 139 140 141 142 143
-               144 145 146 147 148 149 150 151
-               152 153 154 155 156 157 158 159
-               160 161 162 163 164 165 166 167
-               168 169 170 171 172 173 174 175
-               176 177 178 179 180 181 182 183
-               184 185 186 187 188 189 190 191
-               192 193 194 195 196 197 198 199
-               200 201 202 203 204 205 206 207
-               208 209 210 211 212 213 214 215
-               216 217 218 219 220 221 222 223
-               224 225 226 227 228 229 230 231
-               232 233 234 235 236 237 238 239
-               240 241 242 243 244 245 246 247
-               248 249 250 251 252 253 254 255>;
+       brightness-levels = <0 3 255>;
+       num-interpolated-steps = <252>;
 };
 
 &backlight_regulator {
index cc893e1..415c75f 100644 (file)
 
        vopb: vop@ff930000 {
                compatible = "rockchip,rk3288-vop";
-               reg = <0x0 0xff930000 0x0 0x19c>;
+               reg = <0x0 0xff930000 0x0 0x19c>, <0x0 0xff931000 0x0 0x1000>;
                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";
 
        vopl: vop@ff940000 {
                compatible = "rockchip,rk3288-vop";
-               reg = <0x0 0xff940000 0x0 0x19c>;
+               reg = <0x0 0xff940000 0x0 0x19c>, <0x0 0xff941000 0x0 0x1000>;
                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";
                clocks = <&cru PCLK_EFUSE256>;
                clock-names = "pclk_efuse";
 
+               cpu_id: cpu-id@7 {
+                       reg = <0x07 0x10>;
+               };
                cpu_leakage: cpu_leakage@17 {
                        reg = <0x17 0x1>;
                };
index 0e159c8..1aeac33 100644 (file)
        };
 };
 
+&clocks {
+       clocks = <&fin_pll>;
+};
+
 &sdhci0 {
        pinctrl-names = "default";
        pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
index a9a5689..3bf6c45 100644 (file)
        };
 };
 
+&clocks {
+       clocks = <&fin_pll>;
+};
+
 &sdhci0 {
        pinctrl-names = "default";
        pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
index 2e2c1a7..5652048 100644 (file)
                                #clock-cells = <0>;
                        };
 
-                       rtc@f80480b0 {
+                       rtc: rtc@f80480b0 {
                                compatible = "atmel,at91rm9200-rtc";
                                reg = <0xf80480b0 0x30>;
                                interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>;
index b4c0a76..2b64564 100644 (file)
@@ -19,7 +19,7 @@
                m25p,fast-read;
                cdns,page-size = <256>;
                cdns,block-size = <16>;
-               cdns,read-delay = <4>;
+               cdns,read-delay = <3>;
                cdns,tshsl-ns = <50>;
                cdns,tsd2d-ns = <50>;
                cdns,tchsh-ns = <4>;
index ba08624..58288aa 100644 (file)
@@ -60,7 +60,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@00000000 {
                device_type = "memory";
                reg = <0x00000000 0x2000000>;
        };
        status = "okay";
        pinctrl-0 = <&ltdc_pins>;
        pinctrl-names = "default";
-       dma-ranges;
 
        port {
                ltdc_out_rgb: endpoint {
index 2b16648..fcc804e 100644 (file)
@@ -55,7 +55,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@c0000000 {
                device_type = "memory";
                reg = <0xc0000000 0x2000000>;
        };
@@ -95,7 +95,6 @@
 
        joystick {
                compatible = "gpio-keys";
-               #size-cells = <0>;
                pinctrl-0 = <&joystick_pins>;
                pinctrl-names = "default";
                button-0 {
index e19d0fe..30c0f67 100644 (file)
@@ -59,7 +59,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@90000000 {
                device_type = "memory";
                reg = <0x90000000 0x800000>;
        };
index a3ff049..f3ce477 100644 (file)
@@ -60,7 +60,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@00000000 {
                device_type = "memory";
                reg = <0x00000000 0x1000000>;
        };
 };
 
 &ltdc {
-       dma-ranges;
        status = "okay";
 
        port {
index 5ae5213..be002e8 100644 (file)
@@ -8,7 +8,6 @@
                dsi: dsi@40016c00 {
                        compatible = "st,stm32-dsi";
                        reg = <0x40016c00 0x800>;
-                       interrupts = <92>;
                        resets = <&rcc STM32F4_APB2_RESET(DSI)>;
                        reset-names = "apb";
                        clocks = <&rcc 1 CLK_F469_DSI>, <&clk_hse>;
index 0ba9c5b..569d23c 100644 (file)
@@ -55,7 +55,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@c0000000 {
                device_type = "memory";
                reg = <0xC0000000 0x800000>;
        };
index 6f1d0ac..1626e00 100644 (file)
@@ -55,7 +55,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@c0000000 {
                device_type = "memory";
                reg = <0xC0000000 0x1000000>;
        };
index 3acd2e9..e446d31 100644 (file)
@@ -53,7 +53,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@d0000000 {
                device_type = "memory";
                reg = <0xd0000000 0x2000000>;
        };
index e4d3c58..8f39817 100644 (file)
@@ -53,7 +53,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@d0000000 {
                device_type = "memory";
                reg = <0xd0000000 0x2000000>;
        };
index 0a3a7d6..3d1ecb4 100644 (file)
                                status = "disabled";
                        };
 
+                       adc12_ain_pins_a: adc12-ain-0 {
+                               pins {
+                                       pinmux = <STM32_PINMUX('C', 3, ANALOG)>, /* ADC1 in13 */
+                                                <STM32_PINMUX('F', 12, ANALOG)>, /* ADC1 in6 */
+                                                <STM32_PINMUX('F', 13, ANALOG)>, /* ADC2 in2 */
+                                                <STM32_PINMUX('F', 14, ANALOG)>; /* ADC2 in6 */
+                               };
+                       };
+
+                       adc12_usb_cc_pins_a: adc12-usb-cc-pins-0 {
+                               pins {
+                                       pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* ADC12 in18 */
+                                                <STM32_PINMUX('A', 5, ANALOG)>; /* ADC12 in19 */
+                               };
+                       };
+
                        cec_pins_a: cec-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 15, AF4)>;
                                };
                        };
 
+                       dac_ch1_pins_a: dac-ch1 {
+                               pins {
+                                       pinmux = <STM32_PINMUX('A', 4, ANALOG)>;
+                               };
+                       };
+
+                       dac_ch2_pins_a: dac-ch2 {
+                               pins {
+                                       pinmux = <STM32_PINMUX('A', 5, ANALOG)>;
+                               };
+                       };
+
                        dcmi_pins_a: dcmi-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('H', 8,  AF13)>,/* DCMI_HSYNC */
index 2e4742c..628c74a 100644 (file)
                                regulator-name = "vbus_otg";
                                interrupts = <IT_OCP_OTG 0>;
                                interrupt-parent = <&pmic>;
-                               regulator-active-discharge;
                        };
 
                        vbus_sw: pwr_sw2 {
                                regulator-name = "vbus_sw";
                                interrupts = <IT_OCP_SWOUT 0>;
                                interrupt-parent = <&pmic>;
-                               regulator-active-discharge;
+                               regulator-active-discharge = <1>;
                        };
                };
 
        status = "okay";
 };
 
+&pwr_regulators {
+       vdd-supply = <&vdd>;
+       vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
 &rng1 {
        status = "okay";
 };
index 0615d1c..984a47c 100644 (file)
@@ -25,6 +25,7 @@
        };
 
        memory@c0000000 {
+               device_type = "memory";
                reg = <0xc0000000 0x20000000>;
        };
 
                        "Playback" , "MCLK",
                        "Capture" , "MCLK",
                        "MICL" , "Mic Bias";
-               dais = <&sai2a_port &sai2b_port>;
+               dais = <&sai2a_port &sai2b_port &i2s2_port>;
+               status = "okay";
+       };
+};
+
+&adc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&adc12_ain_pins_a>, <&adc12_usb_cc_pins_a>;
+       vdd-supply = <&vdd>;
+       vdda-supply = <&vdd>;
+       vref-supply = <&vrefbuf>;
+       status = "disabled";
+       adc1: adc@0 {
+               /*
+                * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19.
+                * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C:
+                * 5 * (56 + 47kOhms) * 5pF => 2.5us.
+                * Use arbitrary margin here (e.g. 5us).
+                */
+               st,min-sample-time-nsecs = <5000>;
+               /* AIN connector, USB Type-C CC1 & CC2 */
+               st,adc-channels = <0 1 6 13 18 19>;
+               status = "okay";
+       };
+       adc2: adc@100 {
+               /* AIN connector, USB Type-C CC1 & CC2 */
+               st,adc-channels = <0 1 2 6 18 19>;
+               st,min-sample-time-nsecs = <5000>;
                status = "okay";
        };
 };
                reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
                interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
                interrupt-parent = <&gpiog>;
-               pinctrl-names = "default", "sleep";
-               pinctrl-0 = <&ltdc_pins_a>;
-               pinctrl-1 = <&ltdc_pins_sleep_a>;
+               #sound-dai-cells = <0>;
                status = "okay";
 
                ports {
                                        remote-endpoint = <&ltdc_ep0_out>;
                                };
                        };
+
+                       port@3 {
+                               reg = <3>;
+                               sii9022_tx_endpoint: endpoint {
+                                       remote-endpoint = <&i2s2_endpoint>;
+                               };
+                       };
                };
        };
 
 
                        vddcore: buck1 {
                                regulator-name = "vddcore";
-                               regulator-min-microvolt = <800000>;
+                               regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <1350000>;
                                regulator-always-on;
                                regulator-initial-mode = <0>;
                         vbus_sw: pwr_sw2 {
                                regulator-name = "vbus_sw";
                                interrupts = <IT_OCP_SWOUT 0>;
-                               regulator-active-discharge;
+                               regulator-active-discharge = <1>;
                         };
                };
 
        };
 };
 
+&i2s2 {
+       clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
+       clock-names = "pclk", "i2sclk", "x8k", "x11k";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&i2s2_pins_a>;
+       pinctrl-1 = <&i2s2_pins_sleep_a>;
+       status = "okay";
+
+       i2s2_port: port {
+               i2s2_endpoint: endpoint {
+                       remote-endpoint = <&sii9022_tx_endpoint>;
+                       format = "i2s";
+                       mclk-fs = <256>;
+               };
+       };
+};
+
 &ipcc {
        status = "okay";
 };
 };
 
 &ltdc {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&ltdc_pins_a>;
+       pinctrl-1 = <&ltdc_pins_sleep_a>;
        status = "okay";
 
        port {
        status = "okay";
 };
 
+&pwr_regulators {
+       vdd-supply = <&vdd>;
+       vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
 &rng1 {
        status = "okay";
 };
        pinctrl-0 = <&uart4_pins_a>;
        status = "okay";
 };
+
+&vrefbuf {
+       regulator-min-microvolt = <2500000>;
+       regulator-max-microvolt = <2500000>;
+       vdda-supply = <&vdd>;
+       status = "okay";
+};
index 20ea601..d26adcb 100644 (file)
 / {
        model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
        compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
-
-       reg18: reg18 {
-               compatible = "regulator-fixed";
-               regulator-name = "reg18";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               regulator-always-on;
-       };
 };
 
 &dsi {
        };
 };
 
+&i2c1 {
+       touchscreen@38 {
+               compatible = "focaltech,ft6236";
+               reg = <0x38>;
+               interrupts = <2 2>;
+               interrupt-parent = <&gpiof>;
+               interrupt-controller;
+               touchscreen-size-x = <480>;
+               touchscreen-size-y = <800>;
+               status = "okay";
+       };
+};
+
 &ltdc {
        status = "okay";
 
index 1d426ea..b8cc0fb 100644 (file)
                serial0 = &uart4;
        };
 
-       reg11: reg11 {
-               compatible = "regulator-fixed";
-               regulator-name = "reg11";
-               regulator-min-microvolt = <1100000>;
-               regulator-max-microvolt = <1100000>;
-               regulator-always-on;
-       };
-
-       reg18: reg18 {
-               compatible = "regulator-fixed";
-               regulator-name = "reg18";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               regulator-always-on;
-       };
-
        sd_switch: regulator-sd_switch {
                compatible = "regulator-gpio";
                regulator-name = "sd_switch";
 
                gpios = <&gpiof 14 GPIO_ACTIVE_HIGH>;
                gpios-states = <0>;
-               states = <1800000 0x1 2900000 0x0>;
+               states = <1800000 0x1>,
+                        <2900000 0x0>;
+       };
+};
+
+&dac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>;
+       vref-supply = <&vdda>;
+       status = "disabled";
+       dac1: dac@1 {
+               status = "okay";
+       };
+       dac2: dac@2 {
+               status = "okay";
        };
 };
 
 
                        vddcore: buck1 {
                                regulator-name = "vddcore";
-                               regulator-min-microvolt = <800000>;
+                               regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <1350000>;
                                regulator-always-on;
                                regulator-initial-mode = <0>;
                         vbus_sw: pwr_sw2 {
                                regulator-name = "vbus_sw";
                                interrupts = <IT_OCP_SWOUT 0>;
-                               regulator-active-discharge;
+                               regulator-active-discharge = <1>;
                         };
                };
 
        status = "okay";
 };
 
+&pwr_regulators {
+       vdd-supply = <&vdd>;
+       vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
 &rng1 {
        status = "okay";
 };
index 91fc0a3..3789312 100644 (file)
@@ -32,7 +32,6 @@
 
        joystick {
                compatible = "gpio-keys";
-               #size-cells = <0>;
                pinctrl-0 = <&joystick_pins>;
                pinctrl-names = "default";
                button-0 {
 
 &usbh_ehci {
        phys = <&usbphyc_port0>;
-       phy-names = "usb";
        status = "okay";
 };
 
 &usbotg_hs {
        dr_mode = "peripheral";
        phys = <&usbphyc_port1 0>;
-       phy-names = "usb2-phy";
        status = "okay";
 };
 
index f98e037..ed8b258 100644 (file)
                        #reset-cells = <1>;
                };
 
+               pwr_regulators: pwr@50001000 {
+                       compatible = "st,stm32mp1,pwr-reg";
+                       reg = <0x50001000 0x10>;
+
+                       reg11: reg11 {
+                               regulator-name = "reg11";
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                       };
+
+                       reg18: reg18 {
+                               regulator-name = "reg18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       usb33: usb33 {
+                               regulator-name = "usb33";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+
                exti: interrupt-controller@5000d000 {
                        compatible = "st,stm32mp1-exti", "syscon";
                        interrupt-controller;
index 7033a12..d6bb82c 100644 (file)
 &i2c1 {
        status = "okay";
 
-       at24@50 {
+       eeprom@50 {
                compatible = "atmel,24c16";
                pagesize = <16>;
                reg = <0x50>;
index ac76380..2cf34ae 100644 (file)
                                 <&ccu CLK_PLL_VIDEO1_2X>;
                        clock-names = "ahb", "mod", "ddc", "pll-0", "pll-1";
                        resets = <&ccu RST_AHB1_HDMI>;
-                       reset-names = "ahb";
                        dma-names = "ddc-tx", "ddc-rx", "audio-tx";
                        dmas = <&dma 13>, <&dma 13>, <&dma 14>;
                        status = "disabled";
index 3bec3e0..2fd31a0 100644 (file)
        status = "okay";
 };
 
+&i2c0 {
+       clock-frequency = <400000>;
+       status = "okay";
+
+       touchscreen@38 {
+               compatible = "edt,edt-ft5x06";
+               reg = <0x38>;
+               interrupt-parent = <&r_pio>;
+               interrupts = <0 7 IRQ_TYPE_EDGE_FALLING>; /* PL7 */
+               reset-gpios = <&pio 3 5 GPIO_ACTIVE_LOW>; /* PD5 */
+               vcc-supply = <&reg_ldo_io0>;
+               touchscreen-size-x = <1024>;
+               touchscreen-size-y = <600>;
+       };
+};
+
 &i2c1 {
        clock-frequency = <400000>;
        status = "okay";
index 74bb053..53c38de 100644 (file)
                        reg = <0x1c14000 0x400>;
                };
 
+               crypto: crypto@1c15000 {
+                       compatible = "allwinner,sun8i-a83t-crypto";
+                       reg = <0x01c15000 0x1000>;
+                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                       resets = <&ccu RST_BUS_SS>;
+                       clocks = <&ccu CLK_BUS_SS>, <&ccu CLK_SS>;
+                       clock-names = "bus", "mod";
+               };
+
                usb_otg: usb@1c19000 {
                        compatible = "allwinner,sun8i-a83t-musb",
                                     "allwinner,sun8i-a33-musb";
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
new file mode 100644 (file)
index 0000000..c73f599
--- /dev/null
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Karl Palsson <karlp@tweak.net.au>
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "FriendlyARM NanoPi Duo2";
+       compatible = "friendlyarm,nanopi-duo2", "allwinner,sun8i-h3";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               pwr {
+                       label = "nanopi:red:pwr";
+                       gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+                       default-state = "on";
+               };
+
+               status {
+                       label = "nanopi:green:status";
+                       gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>; /* PA10 */
+               };
+       };
+
+       r_gpio_keys {
+               compatible = "gpio-keys";
+
+               k1 {
+                       label = "k1";
+                       linux,code = <BTN_0>;
+                       gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; /* PL3 */
+               };
+       };
+
+       reg_vdd_cpux: vdd-cpux-regulator {
+               compatible = "regulator-gpio";
+               regulator-name = "vdd-cpux";
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-ramp-delay = <50>; /* 4ms */
+
+               enable-active-high;
+               enable-gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+               gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
+               gpios-states = <0x1>;
+               states = <1100000 0x0
+                         1300000 0x1>;
+       };
+
+       reg_vcc_dram: vcc-dram {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc-dram";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+               regulator-always-on;
+               regulator-boot-on;
+               enable-active-high;
+               gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */
+               vin-supply = <&reg_vcc5v0>;
+        };
+
+       reg_vdd_sys: vdd-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd-sys";
+               regulator-min-microvolt = <1200000>;
+               regulator-max-microvolt = <1200000>;
+               regulator-always-on;
+               regulator-boot-on;
+               enable-active-high;
+               gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+               vin-supply = <&reg_vcc5v0>;
+        };
+
+       wifi_pwrseq: wifi_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+               clocks = <&rtc 1>;
+               clock-names = "ext_clock";
+       };
+
+};
+
+&cpu0 {
+       cpu-supply = <&reg_vdd_cpux>;
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&mmc0 {
+       bus-width = <4>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+       status = "okay";
+       vmmc-supply = <&reg_vcc3v3>;
+};
+
+&mmc1 {
+       vmmc-supply = <&reg_vcc3v3>;
+       vqmmc-supply = <&reg_vcc3v3>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       sdio_wifi: sdio_wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&pio>;
+               interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */
+               interrupt-names = "host-wake";
+       };
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&reg_usb0_vbus {
+       gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pa_pins>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>, <&uart2_rts_cts_pins>;
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               clocks = <&rtc 1>;
+               clock-names = "lpo";
+               vbat-supply = <&reg_vcc3v3>;
+               vddio-supply = <&reg_vcc3v3>;
+               device-wakeup-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+               host-wakeup-gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA7 */
+               shutdown-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
+       };
+};
+
+&usb_otg {
+       status = "okay";
+       dr_mode = "otg";
+};
+
+&usbphy {
+       usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+       usb0_vbus-supply = <&reg_usb0_vbus>;
+       status = "okay";
+};
index e37c30e..fe773c7 100644 (file)
        };
 
        soc {
+               deinterlace: deinterlace@1400000 {
+                       compatible = "allwinner,sun8i-h3-deinterlace";
+                       reg = <0x01400000 0x20000>;
+                       clocks = <&ccu CLK_BUS_DEINTERLACE>,
+                                <&ccu CLK_DEINTERLACE>,
+                                <&ccu CLK_DRAM_DEINTERLACE>;
+                       clock-names = "bus", "mod", "ram";
+                       resets = <&ccu RST_BUS_DEINTERLACE>;
+                       interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+                       interconnects = <&mbus 9>;
+                       interconnect-names = "dma-mem";
+               };
+
                syscon: system-control@1c00000 {
                        compatible = "allwinner,sun8i-h3-system-control";
                        reg = <0x01c00000 0x1000>;
                        allwinner,sram = <&ve_sram 1>;
                };
 
+               crypto: crypto@1c15000 {
+                       compatible = "allwinner,sun8i-h3-crypto";
+                       reg = <0x01c15000 0x1000>;
+                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>;
+                       clock-names = "bus", "mod";
+                       resets = <&ccu RST_BUS_CE>;
+               };
+
                mali: gpu@1c40000 {
                        compatible = "allwinner,sun8i-h3-mali", "arm,mali-400";
                        reg = <0x01c40000 0x10000>;
index c9c2688..421dfbb 100644 (file)
                        #phy-cells = <1>;
                };
 
+               crypto: crypto@1c15000 {
+                       compatible = "allwinner,sun8i-r40-crypto";
+                       reg = <0x01c15000 0x1000>;
+                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>;
+                       clock-names = "bus", "mod";
+                       resets = <&ccu RST_BUS_CE>;
+               };
+
                ehci1: usb@1c19000 {
                        compatible = "allwinner,sun8i-r40-ehci", "generic-ehci";
                        reg = <0x01c19000 0x100>;
index b9b6fb0..1d900f5 100644 (file)
                        reg = <0x01700000 0x100>;
                };
 
+               crypto: crypto@1c02000 {
+                       compatible = "allwinner,sun9i-a80-crypto";
+                       reg = <0x01c02000 0x1000>;
+                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                       resets = <&ccu RST_BUS_SS>;
+                       clocks = <&ccu CLK_BUS_SS>, <&ccu CLK_SS>;
+                       clock-names = "bus", "mod";
+               };
+
                mmc0: mmc@1c0f000 {
                        compatible = "allwinner,sun9i-a80-mmc";
                        reg = <0x01c0f000 0x1000>;
                        compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x06000ca0 0x20>;
                        interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                pio: pinctrl@6000800 {
                        compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x08001000 0x20>;
                        interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                prcm@8001400 {
index 107eeaf..0afea59 100644 (file)
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
+               dma-ranges;
                ranges;
 
                display_clocks: clock@1000000 {
                                function = "uart2";
                        };
 
+                       uart2_rts_cts_pins: uart2-rts-cts-pins {
+                               pins = "PA2", "PA3";
+                               function = "uart2";
+                       };
+
                        uart3_pins: uart3-pins {
                                pins = "PA13", "PA14";
                                function = "uart3";
                        };
                };
 
+               mbus: dram-controller@1c62000 {
+                       compatible = "allwinner,sun8i-h3-mbus";
+                       reg = <0x01c62000 0x1000>;
+                       clocks = <&ccu 113>;
+                       dma-ranges = <0x00000000 0x40000000 0xc0000000>;
+                       #interconnect-cells = <1>;
+               };
+
                spi0: spi@1c68000 {
                        compatible = "allwinner,sun8i-h3-spi";
                        reg = <0x01c68000 0x1000>;
index 9af21fe..fb6b3e1 100644 (file)
@@ -1,5 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 / {
+       apbmisc@70000800 {
+               nvidia,long-ram-code;
+       };
+
        clock@60006000 {
                emc-timings-1 {
                        nvidia,ram-code = <1>;
                                clocks = <&tegra_car TEGRA124_CLK_PLL_M>;
                                clock-names = "emc-parent";
                        };
-                       /* TODO: Add 528MHz frequency */
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+                               nvidia,parent-clock-frequency = <528000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-600000000 {
+                               clock-frequency = <600000000>;
+                               nvidia,parent-clock-frequency = <600000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_C_UD>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-792000000 {
+                               clock-frequency = <792000000>;
+                               nvidia,parent-clock-frequency = <792000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+                               clock-names = "emc-parent";
+                       };
+               };
+
+               emc-timings-4 {
+                       nvidia,ram-code = <4>;
+
+                       timing-12750000 {
+                               clock-frequency = <12750000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-20400000 {
+                               clock-frequency = <20400000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-40800000 {
+                               clock-frequency = <40800000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-68000000 {
+                               clock-frequency = <68000000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-102000000 {
+                               clock-frequency = <102000000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-204000000 {
+                               clock-frequency = <204000000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-300000000 {
+                               clock-frequency = <300000000>;
+                               nvidia,parent-clock-frequency = <600000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_C>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-396000000 {
+                               clock-frequency = <396000000>;
+                               nvidia,parent-clock-frequency = <792000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_M>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+                               nvidia,parent-clock-frequency = <528000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-600000000 {
+                               clock-frequency = <600000000>;
+                               nvidia,parent-clock-frequency = <600000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_C_UD>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-792000000 {
+                               clock-frequency = <792000000>;
+                               nvidia,parent-clock-frequency = <792000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+                               clock-names = "emc-parent";
+                       };
+               };
+
+               emc-timings-6 {
+                       nvidia,ram-code = <6>;
+
+                       timing-12750000 {
+                               clock-frequency = <12750000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-20400000 {
+                               clock-frequency = <20400000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-40800000 {
+                               clock-frequency = <40800000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-68000000 {
+                               clock-frequency = <68000000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-102000000 {
+                               clock-frequency = <102000000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-204000000 {
+                               clock-frequency = <204000000>;
+                               nvidia,parent-clock-frequency = <408000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-300000000 {
+                               clock-frequency = <300000000>;
+                               nvidia,parent-clock-frequency = <600000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_C>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-396000000 {
+                               clock-frequency = <396000000>;
+                               nvidia,parent-clock-frequency = <792000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_M>;
+                               clock-names = "emc-parent";
+                       };
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+                               nvidia,parent-clock-frequency = <528000000>;
+                               clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
+                               clock-names = "emc-parent";
+                       };
                        timing-600000000 {
                                clock-frequency = <600000000>;
                                nvidia,parent-clock-frequency = <600000000>;
                                nvidia,emc-zcal-interval = <0x00000000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000a
-                                       0x00000003
-                                       0x0000000b
-                                       0x00000000
-                                       0x00000000
-                                       0x00000003
-                                       0x00000003
-                                       0x00000000
-                                       0x00000006
-                                       0x00000006
-                                       0x00000006
-                                       0x00000002
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00010000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000c
-                                       0x0000000d
-                                       0x0000000f
-                                       0x00000060
-                                       0x00000000
-                                       0x00000018
-                                       0x00000002
-                                       0x00000002
-                                       0x00000001
-                                       0x00000000
-                                       0x00000007
-                                       0x0000000f
-                                       0x00000005
-                                       0x00000005
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000000
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00000064
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x106aa298
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000303
-                                       0x81f1f108
-                                       0x07070004
-                                       0x0000003f
-                                       0x016eeeee
-                                       0x51451400
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x00000007
-                                       0x00000000
-                                       0x00000042
-                                       0x000c000c
-                                       0x00000000
-                                       0x00000003
-                                       0x0000f2f3
-                                       0x800001c5
-                                       0x0000000a
+                                       0x00000000 /* EMC_RC */
+                                       0x00000003 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000000 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000060 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000018 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000007 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000005 /* EMC_TXSR */
+                                       0x00000005 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000064 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000007 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x800001c5 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00000000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000000
-                                       0x00000005
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000a
-                                       0x00000003
-                                       0x0000000b
-                                       0x00000000
-                                       0x00000000
-                                       0x00000003
-                                       0x00000003
-                                       0x00000000
-                                       0x00000006
-                                       0x00000006
-                                       0x00000006
-                                       0x00000002
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00010000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000c
-                                       0x0000000d
-                                       0x0000000f
-                                       0x0000009a
-                                       0x00000000
-                                       0x00000026
-                                       0x00000002
-                                       0x00000002
-                                       0x00000001
-                                       0x00000000
-                                       0x00000007
-                                       0x0000000f
-                                       0x00000006
-                                       0x00000006
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000000
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x000000a0
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x106aa298
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000303
-                                       0x81f1f108
-                                       0x07070004
-                                       0x0000003f
-                                       0x016eeeee
-                                       0x51451400
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x0000000b
-                                       0x00000000
-                                       0x00000042
-                                       0x000c000c
-                                       0x00000000
-                                       0x00000003
-                                       0x0000f2f3
-                                       0x8000023a
-                                       0x0000000a
+                                       0x00000000 /* EMC_RC */
+                                       0x00000005 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000000 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x0000009a /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000026 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000007 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000006 /* EMC_TXSR */
+                                       0x00000006 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x000000a0 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x0000000b /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x8000023a /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00000000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000001
-                                       0x0000000a
-                                       0x00000000
-                                       0x00000001
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000a
-                                       0x00000003
-                                       0x0000000b
-                                       0x00000000
-                                       0x00000000
-                                       0x00000003
-                                       0x00000003
-                                       0x00000000
-                                       0x00000006
-                                       0x00000006
-                                       0x00000006
-                                       0x00000002
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00010000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000c
-                                       0x0000000d
-                                       0x0000000f
-                                       0x00000134
-                                       0x00000000
-                                       0x0000004d
-                                       0x00000002
-                                       0x00000002
-                                       0x00000001
-                                       0x00000000
-                                       0x00000008
-                                       0x0000000f
-                                       0x0000000c
-                                       0x0000000c
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000000
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x0000013f
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x106aa298
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000303
-                                       0x81f1f108
-                                       0x07070004
-                                       0x0000003f
-                                       0x016eeeee
-                                       0x51451400
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x00000015
-                                       0x00000000
-                                       0x00000042
-                                       0x000c000c
-                                       0x00000000
-                                       0x00000003
-                                       0x0000f2f3
-                                       0x80000370
-                                       0x0000000a
+                                       0x00000001 /* EMC_RC */
+                                       0x0000000a /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000001 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000134 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x0000004d /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000008 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000000c /* EMC_TXSR */
+                                       0x0000000c /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x0000013f /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000015 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x80000370 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00000000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000003
-                                       0x00000011
-                                       0x00000000
-                                       0x00000002
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000a
-                                       0x00000003
-                                       0x0000000b
-                                       0x00000000
-                                       0x00000000
-                                       0x00000003
-                                       0x00000003
-                                       0x00000000
-                                       0x00000006
-                                       0x00000006
-                                       0x00000006
-                                       0x00000002
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00010000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000c
-                                       0x0000000d
-                                       0x0000000f
-                                       0x00000202
-                                       0x00000000
-                                       0x00000080
-                                       0x00000002
-                                       0x00000002
-                                       0x00000001
-                                       0x00000000
-                                       0x0000000f
-                                       0x0000000f
-                                       0x00000013
-                                       0x00000013
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000001
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00000213
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x106aa298
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000303
-                                       0x81f1f108
-                                       0x07070004
-                                       0x0000003f
-                                       0x016eeeee
-                                       0x51451400
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x00000022
-                                       0x00000000
-                                       0x00000042
-                                       0x000c000c
-                                       0x00000000
-                                       0x00000003
-                                       0x0000f2f3
-                                       0x8000050e
-                                       0x0000000a
+                                       0x00000003 /* EMC_RC */
+                                       0x00000011 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000002 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000202 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000080 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x0000000f /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000013 /* EMC_TXSR */
+                                       0x00000013 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000001 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000213 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000022 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x8000050e /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00000000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000004
-                                       0x0000001a
-                                       0x00000000
-                                       0x00000003
-                                       0x00000001
-                                       0x00000004
-                                       0x0000000a
-                                       0x00000003
-                                       0x0000000b
-                                       0x00000001
-                                       0x00000001
-                                       0x00000003
-                                       0x00000003
-                                       0x00000000
-                                       0x00000006
-                                       0x00000006
-                                       0x00000006
-                                       0x00000002
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00010000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x0000000c
-                                       0x0000000d
-                                       0x0000000f
-                                       0x00000304
-                                       0x00000000
-                                       0x000000c1
-                                       0x00000002
-                                       0x00000002
-                                       0x00000001
-                                       0x00000000
-                                       0x00000018
-                                       0x0000000f
-                                       0x0000001c
-                                       0x0000001c
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000003
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x0000031c
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x106aa298
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x000fc000
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x0000fc00
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000303
-                                       0x81f1f108
-                                       0x07070004
-                                       0x0000003f
-                                       0x016eeeee
-                                       0x51451400
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x00000033
-                                       0x00000000
-                                       0x00000042
-                                       0x000c000c
-                                       0x00000000
-                                       0x00000003
-                                       0x0000f2f3
-                                       0x80000713
-                                       0x0000000a
+                                       0x00000004 /* EMC_RC */
+                                       0x0000001a /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000003 /* EMC_RAS */
+                                       0x00000001 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000001 /* EMC_RD_RCD */
+                                       0x00000001 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000304 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000000c1 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000018 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000001c /* EMC_TXSR */
+                                       0x0000001c /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000003 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x0000031c /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000033 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x80000713 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00020000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000009
-                                       0x00000035
-                                       0x00000000
-                                       0x00000007
-                                       0x00000002
-                                       0x00000005
-                                       0x0000000a
-                                       0x00000003
-                                       0x0000000b
-                                       0x00000002
-                                       0x00000002
-                                       0x00000003
-                                       0x00000003
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00000006
-                                       0x00000002
-                                       0x00000000
-                                       0x00000004
-                                       0x00000006
-                                       0x00010000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000003
-                                       0x0000000d
-                                       0x0000000f
-                                       0x00000011
-                                       0x00000607
-                                       0x00000000
-                                       0x00000181
-                                       0x00000002
-                                       0x00000002
-                                       0x00000001
-                                       0x00000000
-                                       0x00000032
-                                       0x0000000f
-                                       0x00000038
-                                       0x00000038
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000007
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00000638
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x106aa298
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00064000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00004000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00090000
-                                       0x00090000
-                                       0x00094000
-                                       0x00094000
-                                       0x00009400
-                                       0x00009000
-                                       0x00009000
-                                       0x00009000
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000303
-                                       0x81f1f108
-                                       0x07070004
-                                       0x0000003f
-                                       0x016eeeee
-                                       0x51451400
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x00000066
-                                       0x00000000
-                                       0x00000100
-                                       0x000c000c
-                                       0x00000000
-                                       0x00000003
-                                       0x0000d2b3
-                                       0x80000d22
-                                       0x0000000a
+                                       0x00000009 /* EMC_RC */
+                                       0x00000035 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000007 /* EMC_RAS */
+                                       0x00000002 /* EMC_RP */
+                                       0x00000005 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000002 /* EMC_RD_RCD */
+                                       0x00000002 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000005 /* EMC_WDV */
+                                       0x00000005 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000004 /* EMC_EINPUT */
+                                       0x00000006 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000003 /* EMC_QRST */
+                                       0x0000000d /* EMC_QSAFE */
+                                       0x0000000f /* EMC_RDV */
+                                       0x00000011 /* EMC_RDV_MASK */
+                                       0x00000607 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000181 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000032 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000038 /* EMC_TXSR */
+                                       0x00000038 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000007 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000638 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00090000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00090000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00094000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00094000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00009400 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000066 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000d2b3 /* EMC_CFG_PIPE */
+                                       0x80000d22 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00020000>;
 
                                nvidia,emc-configuration = <
-                                       0x0000000d
-                                       0x0000004c
-                                       0x00000000
-                                       0x00000009
-                                       0x00000003
-                                       0x00000004
-                                       0x00000008
-                                       0x00000002
-                                       0x00000009
-                                       0x00000003
-                                       0x00000003
-                                       0x00000002
-                                       0x00000002
-                                       0x00000000
-                                       0x00000003
-                                       0x00000003
-                                       0x00000005
-                                       0x00000002
-                                       0x00000000
-                                       0x00000002
-                                       0x00000007
-                                       0x00020000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000001
-                                       0x0000000e
-                                       0x00000010
-                                       0x00000012
-                                       0x000008e4
-                                       0x00000000
-                                       0x00000239
-                                       0x00000001
-                                       0x00000008
-                                       0x00000001
-                                       0x00000000
-                                       0x0000004a
-                                       0x0000000e
-                                       0x00000051
-                                       0x00000200
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000009
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00000924
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x104ab098
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00098000
-                                       0x00098000
-                                       0x00000000
-                                       0x00098000
-                                       0x00098000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00060000
-                                       0x00060000
-                                       0x00060000
-                                       0x00060000
-                                       0x00006000
-                                       0x00006000
-                                       0x00006000
-                                       0x00006000
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000101
-                                       0x81f1f108
-                                       0x07070004
-                                       0x00000000
-                                       0x016eeeee
-                                       0x51451420
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x00000096
-                                       0x00000000
-                                       0x00000100
-                                       0x0174000c
-                                       0x00000000
-                                       0x00000003
-                                       0x000052a3
-                                       0x800012d7
-                                       0x00000009
+                                       0x0000000d /* EMC_RC */
+                                       0x0000004c /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000009 /* EMC_RAS */
+                                       0x00000003 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x00000008 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x00000009 /* EMC_W2P */
+                                       0x00000003 /* EMC_RD_RCD */
+                                       0x00000003 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000005 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x00000007 /* EMC_EINPUT_DURATION */
+                                       0x00020000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x0000000e /* EMC_QSAFE */
+                                       0x00000010 /* EMC_RDV */
+                                       0x00000012 /* EMC_RDV_MASK */
+                                       0x000008e4 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000239 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000001 /* EMC_PDEX2WR */
+                                       0x00000008 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x0000004a /* EMC_AR2PDEN */
+                                       0x0000000e /* EMC_RW2PDEN */
+                                       0x00000051 /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000009 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000924 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000096 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x0174000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000052a3 /* EMC_CFG_PIPE */
+                                       0x800012d7 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x00000009 /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00020000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000012
-                                       0x00000065
-                                       0x00000000
-                                       0x0000000c
-                                       0x00000004
-                                       0x00000005
-                                       0x00000008
-                                       0x00000002
-                                       0x0000000a
-                                       0x00000004
-                                       0x00000004
-                                       0x00000002
-                                       0x00000002
-                                       0x00000000
-                                       0x00000003
-                                       0x00000003
-                                       0x00000005
-                                       0x00000002
-                                       0x00000000
-                                       0x00000001
-                                       0x00000008
-                                       0x00020000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x0000000f
-                                       0x00000010
-                                       0x00000012
-                                       0x00000bd1
-                                       0x00000000
-                                       0x000002f4
-                                       0x00000001
-                                       0x00000008
-                                       0x00000001
-                                       0x00000000
-                                       0x00000063
-                                       0x0000000f
-                                       0x0000006b
-                                       0x00000200
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x0000000d
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x00000c11
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x104ab098
-                                       0x002c00a0
-                                       0x00008000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00030000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00070000
-                                       0x00070000
-                                       0x00000000
-                                       0x00070000
-                                       0x00070000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00048000
-                                       0x00048000
-                                       0x00048000
-                                       0x00048000
-                                       0x00004800
-                                       0x00004800
-                                       0x00004800
-                                       0x00004800
-                                       0x10000280
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc081
-                                       0x00000101
-                                       0x81f1f108
-                                       0x07070004
-                                       0x00000000
-                                       0x016eeeee
-                                       0x51451420
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0000003f
-                                       0x000000c6
-                                       0x00000000
-                                       0x00000100
-                                       0x015b000c
-                                       0x00000000
-                                       0x00000003
-                                       0x000052a3
-                                       0x8000188b
-                                       0x00000009
+                                       0x00000012 /* EMC_RC */
+                                       0x00000065 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x0000000c /* EMC_RAS */
+                                       0x00000004 /* EMC_RP */
+                                       0x00000005 /* EMC_R2W */
+                                       0x00000008 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x0000000a /* EMC_W2P */
+                                       0x00000004 /* EMC_RD_RCD */
+                                       0x00000004 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000005 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000001 /* EMC_EINPUT */
+                                       0x00000008 /* EMC_EINPUT_DURATION */
+                                       0x00020000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000000 /* EMC_QRST */
+                                       0x0000000f /* EMC_QSAFE */
+                                       0x00000010 /* EMC_RDV */
+                                       0x00000012 /* EMC_RDV_MASK */
+                                       0x00000bd1 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000002f4 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000001 /* EMC_PDEX2WR */
+                                       0x00000008 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000063 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000006b /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x0000000d /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000c11 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x000000c6 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x015b000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000052a3 /* EMC_CFG_PIPE */
+                                       0x8000188b /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x00000009 /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73300000>;
+                               nvidia,emc-cfg-2 = <0x0000089d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100002>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80000941>;
+                               nvidia,emc-mrs-wait-cnt = <0x013a000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0123133d>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000018 /* EMC_RC */
+                                       0x00000088 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000011 /* EMC_RAS */
+                                       0x00000006 /* EMC_RP */
+                                       0x00000006 /* EMC_R2W */
+                                       0x00000009 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x0000000d /* EMC_W2P */
+                                       0x00000006 /* EMC_RD_RCD */
+                                       0x00000006 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000007 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x00000009 /* EMC_EINPUT_DURATION */
+                                       0x00040000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x00000010 /* EMC_QSAFE */
+                                       0x00000013 /* EMC_RDV */
+                                       0x00000015 /* EMC_RDV_MASK */
+                                       0x00000fd6 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000003f5 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x0000000b /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000084 /* EMC_AR2PDEN */
+                                       0x00000012 /* EMC_RW2PDEN */
+                                       0x0000008f /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000013 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000006 /* EMC_TCLKSTABLE */
+                                       0x00000006 /* EMC_TCLKSTOP */
+                                       0x00001017 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0xe01200b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS0 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS1 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS2 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS3 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS4 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS5 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS6 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS7 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS8 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS9 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS10 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS11 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS12 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS13 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS14 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000001 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000001 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x013a000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000042a0 /* EMC_CFG_PIPE */
+                                       0x80002062 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000b /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00020000>;
 
                                nvidia,emc-configuration = <
-                                       0x0000001c
-                                       0x0000009a
-                                       0x00000000
-                                       0x00000013
-                                       0x00000007
-                                       0x00000007
-                                       0x0000000b
-                                       0x00000003
-                                       0x00000010
-                                       0x00000007
-                                       0x00000007
-                                       0x00000002
-                                       0x00000002
-                                       0x00000000
-                                       0x00000005
-                                       0x00000005
-                                       0x0000000a
-                                       0x00000002
-                                       0x00000000
-                                       0x00000003
-                                       0x0000000b
-                                       0x00070000
-                                       0x00000003
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000002
-                                       0x00000012
-                                       0x00000016
-                                       0x00000018
-                                       0x00001208
-                                       0x00000000
-                                       0x00000482
-                                       0x00000002
-                                       0x0000000d
-                                       0x00000001
-                                       0x00000000
-                                       0x00000096
-                                       0x00000015
-                                       0x000000a2
-                                       0x00000200
-                                       0x00000004
-                                       0x00000005
-                                       0x00000004
-                                       0x00000015
-                                       0x00000000
-                                       0x00000006
-                                       0x00000006
-                                       0x00001249
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x104ab098
-                                       0xe00e00b1
-                                       0x00008000
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00048000
-                                       0x00048000
-                                       0x00000000
-                                       0x00048000
-                                       0x00048000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000004
-                                       0x00000004
-                                       0x00000002
-                                       0x00000005
-                                       0x00000006
-                                       0x00000003
-                                       0x00000006
-                                       0x00000005
-                                       0x00000004
-                                       0x00000004
-                                       0x00000002
-                                       0x00000005
-                                       0x00000006
-                                       0x00000003
-                                       0x00000006
-                                       0x00000005
-                                       0x0000000e
-                                       0x0000000e
-                                       0x0000000e
-                                       0x0000000e
-                                       0x0000000e
-                                       0x0000000e
-                                       0x0000000e
-                                       0x0000000e
-                                       0x100002a0
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc085
-                                       0x00000101
-                                       0x81f1f108
-                                       0x07070004
-                                       0x00000000
-                                       0x016eeeee
-                                       0x51451420
-                                       0x00514514
-                                       0x00514514
-                                       0x51451400
-                                       0x0606003f
-                                       0x00000000
-                                       0x00000000
-                                       0x00000100
-                                       0x0128000c
-                                       0x00000000
-                                       0x00000003
-                                       0x000040a0
-                                       0x800024aa
-                                       0x0000000e
+                                       0x0000001c /* EMC_RC */
+                                       0x0000009a /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000013 /* EMC_RAS */
+                                       0x00000007 /* EMC_RP */
+                                       0x00000007 /* EMC_R2W */
+                                       0x0000000b /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x00000010 /* EMC_W2P */
+                                       0x00000007 /* EMC_RD_RCD */
+                                       0x00000007 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000005 /* EMC_WDV */
+                                       0x00000005 /* EMC_WDV_MASK */
+                                       0x0000000a /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000003 /* EMC_EINPUT */
+                                       0x0000000b /* EMC_EINPUT_DURATION */
+                                       0x00070000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000002 /* EMC_QRST */
+                                       0x00000012 /* EMC_QSAFE */
+                                       0x00000016 /* EMC_RDV */
+                                       0x00000018 /* EMC_RDV_MASK */
+                                       0x00001208 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000482 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x0000000d /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000096 /* EMC_AR2PDEN */
+                                       0x00000015 /* EMC_RW2PDEN */
+                                       0x000000a2 /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000015 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000006 /* EMC_TCLKSTABLE */
+                                       0x00000006 /* EMC_TCLKSTOP */
+                                       0x00001249 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0xe00e00b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS0 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS1 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS2 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS3 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS4 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS5 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS6 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS7 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS8 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS9 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS10 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS11 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS12 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS13 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS14 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x0128000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000040a0 /* EMC_CFG_PIPE */
+                                       0x800024aa /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000e /* EMC_QPOP */
                                >;
                        };
 
                                nvidia,emc-zcal-interval = <0x00020000>;
 
                                nvidia,emc-configuration = <
-                                       0x00000025
-                                       0x000000cc
-                                       0x00000000
-                                       0x0000001a
-                                       0x00000009
-                                       0x00000008
-                                       0x0000000d
-                                       0x00000004
-                                       0x00000013
-                                       0x00000009
-                                       0x00000009
-                                       0x00000003
-                                       0x00000002
-                                       0x00000000
-                                       0x00000006
-                                       0x00000006
-                                       0x0000000b
-                                       0x00000002
-                                       0x00000000
-                                       0x00000002
-                                       0x0000000d
-                                       0x00080000
-                                       0x00000004
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000001
-                                       0x00000014
-                                       0x00000018
-                                       0x0000001a
-                                       0x000017e2
-                                       0x00000000
-                                       0x000005f8
-                                       0x00000003
-                                       0x00000011
-                                       0x00000001
-                                       0x00000000
-                                       0x000000c6
-                                       0x00000018
-                                       0x000000d6
-                                       0x00000200
-                                       0x00000005
-                                       0x00000006
-                                       0x00000005
-                                       0x0000001d
-                                       0x00000000
-                                       0x00000008
-                                       0x00000008
-                                       0x00001822
-                                       0x00000000
-                                       0x80000005
-                                       0x00000000
-                                       0x104ab198
-                                       0xe00700b1
-                                       0x00008000
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000005
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00034000
-                                       0x00034000
-                                       0x00000000
-                                       0x00034000
-                                       0x00034000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000000
-                                       0x00000008
-                                       0x00000008
-                                       0x00000005
-                                       0x00000009
-                                       0x00000009
-                                       0x00000007
-                                       0x00000009
-                                       0x00000008
-                                       0x00000008
-                                       0x00000008
-                                       0x00000005
-                                       0x00000009
-                                       0x00000009
-                                       0x00000007
-                                       0x00000009
-                                       0x00000008
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x0000000a
-                                       0x100002a0
-                                       0x00000000
-                                       0x00111111
-                                       0x00000000
-                                       0x00000000
-                                       0x77ffc085
-                                       0x00000101
-                                       0x81f1f108
-                                       0x07070004
-                                       0x00000000
-                                       0x016eeeee
-                                       0x61861820
-                                       0x00514514
-                                       0x00514514
-                                       0x61861800
-                                       0x0606003f
-                                       0x00000000
-                                       0x00000000
-                                       0x00000100
-                                       0x00f8000c
-                                       0x00000007
-                                       0x00000004
-                                       0x00004080
-                                       0x80003012
-                                       0x0000000f
+                                       0x00000025 /* EMC_RC */
+                                       0x000000cc /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x0000001a /* EMC_RAS */
+                                       0x00000009 /* EMC_RP */
+                                       0x00000008 /* EMC_R2W */
+                                       0x0000000d /* EMC_W2R */
+                                       0x00000004 /* EMC_R2P */
+                                       0x00000013 /* EMC_W2P */
+                                       0x00000009 /* EMC_RD_RCD */
+                                       0x00000009 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x0000000b /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x0000000d /* EMC_EINPUT_DURATION */
+                                       0x00080000 /* EMC_PUTERM_EXTRA */
+                                       0x00000004 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x00000014 /* EMC_QSAFE */
+                                       0x00000018 /* EMC_RDV */
+                                       0x0000001a /* EMC_RDV_MASK */
+                                       0x000017e2 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000005f8 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000003 /* EMC_PDEX2WR */
+                                       0x00000011 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x000000c6 /* EMC_AR2PDEN */
+                                       0x00000018 /* EMC_RW2PDEN */
+                                       0x000000d6 /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000005 /* EMC_TCKE */
+                                       0x00000006 /* EMC_TCKESR */
+                                       0x00000005 /* EMC_TPD */
+                                       0x0000001d /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000008 /* EMC_TCLKSTABLE */
+                                       0x00000008 /* EMC_TCLKSTOP */
+                                       0x00001822 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x80000005 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab198 /* EMC_FBIO_CFG5 */
+                                       0xe00700b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00000005 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000007 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000007 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x61861820 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x61861800 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x00f8000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000007 /* EMC_CTT */
+                                       0x00000004 /* EMC_CTT_DURATION */
+                                       0x00004080 /* EMC_CFG_PIPE */
+                                       0x80003012 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000f /* EMC_QPOP */
                                >;
                        };
-
                };
-       };
-
-       memory-controller@70019000 {
-               emc-timings-1 {
-                       nvidia,ram-code = <1>;
 
+               emc-timings-4 {
+                       nvidia,ram-code = <4>;
 
                        timing-12750000 {
                                clock-frequency = <12750000>;
 
-                               nvidia,emem-configuration = <
-                                       0x40040001
-                                       0x8000000a
-                                       0x00000001
-                                       0x00000001
-                                       0x00000002
-                                       0x00000000
-                                       0x00000002
-                                       0x00000001
-                                       0x00000002
-                                       0x00000008
-                                       0x00000003
-                                       0x00000002
-                                       0x00000003
-                                       0x00000006
-                                       0x06030203
-                                       0x000a0402
-                                       0x77e30303
-                                       0x70000f03
-                                       0x001f0000
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100003>;
+                               nvidia,emc-mode-2 = <0x00200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000000 /* EMC_RC */
+                                       0x00000004 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000000 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000005 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000060 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000018 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000007 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000005 /* EMC_TXSR */
+                                       0x00000005 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000064 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000007 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000e000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x800001c5 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                        timing-20400000 {
                                clock-frequency = <20400000>;
 
-                               nvidia,emem-configuration = <
-                                       0x40020001
-                                       0x80000012
-                                       0x00000001
-                                       0x00000001
-                                       0x00000002
-                                       0x00000000
-                                       0x00000002
-                                       0x00000001
-                                       0x00000002
-                                       0x00000008
-                                       0x00000003
-                                       0x00000002
-                                       0x00000003
-                                       0x00000006
-                                       0x06030203
-                                       0x000a0402
-                                       0x76230303
-                                       0x70000f03
-                                       0x001f0000
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100003>;
+                               nvidia,emc-mode-2 = <0x00200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000000 /* EMC_RC */
+                                       0x00000007 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000000 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000005 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x0000009a /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000026 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000007 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000008 /* EMC_TXSR */
+                                       0x00000008 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x000000a0 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x0000000b /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000e000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x8000023a /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                        timing-40800000 {
                                clock-frequency = <40800000>;
 
-                               nvidia,emem-configuration = <
-                                       0xa0000001
-                                       0x80000017
-                                       0x00000001
-                                       0x00000001
-                                       0x00000002
-                                       0x00000000
-                                       0x00000002
-                                       0x00000001
-                                       0x00000002
-                                       0x00000008
-                                       0x00000003
-                                       0x00000002
-                                       0x00000003
-                                       0x00000006
-                                       0x06030203
-                                       0x000a0402
-                                       0x74a30303
-                                       0x70000f03
-                                       0x001f0000
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100003>;
+                               nvidia,emc-mode-2 = <0x00200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000001 /* EMC_RC */
+                                       0x0000000e /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000001 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000005 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000134 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x0000004d /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x0000000c /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000000f /* EMC_TXSR */
+                                       0x0000000f /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x0000013f /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000015 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000e000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x80000370 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                        timing-68000000 {
                                clock-frequency = <68000000>;
 
-                               nvidia,emem-configuration = <
-                                       0x00000001
-                                       0x8000001e
-                                       0x00000001
-                                       0x00000001
-                                       0x00000002
-                                       0x00000000
-                                       0x00000002
-                                       0x00000001
-                                       0x00000002
-                                       0x00000008
-                                       0x00000003
-                                       0x00000002
-                                       0x00000003
-                                       0x00000006
-                                       0x06030203
-                                       0x000a0402
-                                       0x74230403
-                                       0x70000f03
-                                       0x001f0000
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100003>;
+                               nvidia,emc-mode-2 = <0x00200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000003 /* EMC_RC */
+                                       0x00000017 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000002 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000005 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000202 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000080 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000015 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000019 /* EMC_TXSR */
+                                       0x00000019 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000001 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000213 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000022 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000e000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x8000050e /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                        timing-102000000 {
                                clock-frequency = <102000000>;
 
-                               nvidia,emem-configuration = <
-                                       0x08000001
-                                       0x80000026
-                                       0x00000001
-                                       0x00000001
-                                       0x00000003
-                                       0x00000000
-                                       0x00000002
-                                       0x00000001
-                                       0x00000002
-                                       0x00000008
-                                       0x00000003
-                                       0x00000002
-                                       0x00000003
-                                       0x00000006
-                                       0x06030203
-                                       0x000a0403
-                                       0x73c30504
-                                       0x70000f03
-                                       0x001f0000
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100003>;
+                               nvidia,emc-mode-2 = <0x00200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000004 /* EMC_RC */
+                                       0x00000023 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000003 /* EMC_RAS */
+                                       0x00000001 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000005 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000001 /* EMC_RD_RCD */
+                                       0x00000001 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000304 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000000c1 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000021 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000025 /* EMC_TXSR */
+                                       0x00000025 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000003 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x0000031c /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00080000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00008000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000033 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000e000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x80000713 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
                                >;
                        };
 
                        timing-204000000 {
                                clock-frequency = <204000000>;
 
-                               nvidia,emem-configuration = <
-                                       0x01000003
-                                       0x80000040
-                                       0x00000001
-                                       0x00000001
-                                       0x00000005
-                                       0x00000002
-                                       0x00000004
-                                       0x00000001
-                                       0x00000002
-                                       0x00000008
-                                       0x00000003
-                                       0x00000002
-                                       0x00000004
-                                       0x00000006
-                                       0x06040203
-                                       0x000a0405
-                                       0x73840a06
-                                       0x70000f03
-                                       0x001f0000
-                               >;
-                       };
-
-                       timing-300000000 {
-                               clock-frequency = <300000000>;
-
-                               nvidia,emem-configuration = <
-                                       0x08000004
-                                       0x80000040
-                                       0x00000001
-                                       0x00000002
-                                       0x00000007
-                                       0x00000004
-                                       0x00000005
-                                       0x00000001
-                                       0x00000002
-                                       0x00000007
-                                       0x00000002
-                                       0x00000002
-                                       0x00000004
-                                       0x00000006
-                                       0x06040202
-                                       0x000b0607
-                                       0x77450e08
-                                       0x70000f03
-                                       0x001f0000
-                               >;
-                       };
-
-                       timing-396000000 {
-                               clock-frequency = <396000000>;
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x0000088d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100003>;
+                               nvidia,emc-mode-2 = <0x00200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000e000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000009 /* EMC_RC */
+                                       0x00000047 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000006 /* EMC_RAS */
+                                       0x00000002 /* EMC_RP */
+                                       0x00000005 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000005 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000002 /* EMC_RD_RCD */
+                                       0x00000002 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000005 /* EMC_WDV */
+                                       0x00000005 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000004 /* EMC_EINPUT */
+                                       0x00000006 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000003 /* EMC_QRST */
+                                       0x0000000d /* EMC_QSAFE */
+                                       0x0000000f /* EMC_RDV */
+                                       0x00000011 /* EMC_RDV_MASK */
+                                       0x00000607 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000181 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000044 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000004a /* EMC_TXSR */
+                                       0x0000004a /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000007 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000638 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00090000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00090000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00094000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00094000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00009400 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000066 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000e000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000d2b3 /* EMC_CFG_PIPE */
+                                       0x80000d22 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-300000000 {
+                               clock-frequency = <300000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73340000>;
+                               nvidia,emc-cfg-2 = <0x000008d5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100002>;
+                               nvidia,emc-mode-2 = <0x00200000>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00000321>;
+                               nvidia,emc-mrs-wait-cnt = <0x0117000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x0000000d /* EMC_RC */
+                                       0x00000067 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000009 /* EMC_RAS */
+                                       0x00000003 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x00000008 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x00000009 /* EMC_W2P */
+                                       0x00000003 /* EMC_RD_RCD */
+                                       0x00000003 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000005 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x00000007 /* EMC_EINPUT_DURATION */
+                                       0x00020000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x0000000e /* EMC_QSAFE */
+                                       0x00000010 /* EMC_RDV */
+                                       0x00000012 /* EMC_RDV_MASK */
+                                       0x000008e4 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000239 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000001 /* EMC_PDEX2WR */
+                                       0x00000008 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000065 /* EMC_AR2PDEN */
+                                       0x0000000e /* EMC_RW2PDEN */
+                                       0x0000006c /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000009 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000924 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000096 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x0117000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000052a3 /* EMC_CFG_PIPE */
+                                       0x800012d7 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x00000009 /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-396000000 {
+                               clock-frequency = <396000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73340000>;
+                               nvidia,emc-cfg-2 = <0x00000895>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100002>;
+                               nvidia,emc-mode-2 = <0x00200000>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00000521>;
+                               nvidia,emc-mrs-wait-cnt = <0x00f5000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000011 /* EMC_RC */
+                                       0x00000089 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x0000000c /* EMC_RAS */
+                                       0x00000004 /* EMC_RP */
+                                       0x00000005 /* EMC_R2W */
+                                       0x00000008 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x0000000a /* EMC_W2P */
+                                       0x00000004 /* EMC_RD_RCD */
+                                       0x00000004 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000005 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000001 /* EMC_EINPUT */
+                                       0x00000008 /* EMC_EINPUT_DURATION */
+                                       0x00020000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000000 /* EMC_QRST */
+                                       0x0000000f /* EMC_QSAFE */
+                                       0x00000010 /* EMC_RDV */
+                                       0x00000012 /* EMC_RDV_MASK */
+                                       0x00000bd1 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000002f4 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000001 /* EMC_PDEX2WR */
+                                       0x00000008 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000087 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000008f /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x0000000d /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000c11 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x000000c6 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x00f5000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000052a3 /* EMC_CFG_PIPE */
+                                       0x8000188b /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x00000009 /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73300000>;
+                               nvidia,emc-cfg-2 = <0x0000089d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100002>;
+                               nvidia,emc-mode-2 = <0x00200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00000941>;
+                               nvidia,emc-mrs-wait-cnt = <0x00c8000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0123133d>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000018 /* EMC_RC */
+                                       0x000000b7 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000010 /* EMC_RAS */
+                                       0x00000006 /* EMC_RP */
+                                       0x00000006 /* EMC_R2W */
+                                       0x00000009 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x0000000d /* EMC_W2P */
+                                       0x00000006 /* EMC_RD_RCD */
+                                       0x00000006 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000007 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x00000009 /* EMC_EINPUT_DURATION */
+                                       0x00040000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x00000010 /* EMC_QSAFE */
+                                       0x00000013 /* EMC_RDV */
+                                       0x00000015 /* EMC_RDV_MASK */
+                                       0x00000fd6 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000003f5 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x0000000b /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x000000b4 /* EMC_AR2PDEN */
+                                       0x00000012 /* EMC_RW2PDEN */
+                                       0x000000bf /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000013 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000006 /* EMC_TCLKSTABLE */
+                                       0x00000006 /* EMC_TCLKSTOP */
+                                       0x00001017 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0xe01200b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS0 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS1 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS2 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS3 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS4 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS5 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS6 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS7 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS8 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS9 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS10 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS11 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS12 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS13 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS14 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000001 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000001 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x00c8000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000042a0 /* EMC_CFG_PIPE */
+                                       0x80002062 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000b /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-600000000 {
+                               clock-frequency = <600000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73300000>;
+                               nvidia,emc-cfg-2 = <0x0000089d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100002>;
+                               nvidia,emc-mode-2 = <0x00200010>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00000b61>;
+                               nvidia,emc-mrs-wait-cnt = <0x00b0000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0121113d>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x0000001b /* EMC_RC */
+                                       0x000000d0 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000013 /* EMC_RAS */
+                                       0x00000007 /* EMC_RP */
+                                       0x00000007 /* EMC_R2W */
+                                       0x0000000b /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x00000010 /* EMC_W2P */
+                                       0x00000007 /* EMC_RD_RCD */
+                                       0x00000007 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000005 /* EMC_WDV */
+                                       0x00000005 /* EMC_WDV_MASK */
+                                       0x0000000a /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000003 /* EMC_EINPUT */
+                                       0x0000000b /* EMC_EINPUT_DURATION */
+                                       0x00070000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000002 /* EMC_QRST */
+                                       0x00000012 /* EMC_QSAFE */
+                                       0x00000016 /* EMC_RDV */
+                                       0x00000018 /* EMC_RDV_MASK */
+                                       0x00001208 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000482 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x0000000d /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x000000cc /* EMC_AR2PDEN */
+                                       0x00000015 /* EMC_RW2PDEN */
+                                       0x000000d8 /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000015 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000006 /* EMC_TCLKSTABLE */
+                                       0x00000006 /* EMC_TCLKSTOP */
+                                       0x00001249 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0xe00e00b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS0 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS1 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS2 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS3 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS4 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS5 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS6 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS7 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS8 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS9 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS10 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS11 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS12 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS13 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS14 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x00b0000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000040a0 /* EMC_CFG_PIPE */
+                                       0x800024aa /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000e /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-792000000 {
+                               clock-frequency = <792000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73300000>;
+                               nvidia,emc-cfg-2 = <0x0080089d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x00100002>;
+                               nvidia,emc-mode-2 = <0x00200418>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x00000d71>;
+                               nvidia,emc-mrs-wait-cnt = <0x006f000e>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040000>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0120113d>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000024 /* EMC_RC */
+                                       0x00000114 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000019 /* EMC_RAS */
+                                       0x0000000a /* EMC_RP */
+                                       0x00000008 /* EMC_R2W */
+                                       0x0000000d /* EMC_W2R */
+                                       0x00000004 /* EMC_R2P */
+                                       0x00000013 /* EMC_W2P */
+                                       0x0000000a /* EMC_RD_RCD */
+                                       0x0000000a /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x0000000b /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x0000000d /* EMC_EINPUT_DURATION */
+                                       0x00080000 /* EMC_PUTERM_EXTRA */
+                                       0x00000004 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x00000014 /* EMC_QSAFE */
+                                       0x00000018 /* EMC_RDV */
+                                       0x0000001a /* EMC_RDV_MASK */
+                                       0x000017e2 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000005f8 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000003 /* EMC_PDEX2WR */
+                                       0x00000011 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x0000010d /* EMC_AR2PDEN */
+                                       0x00000018 /* EMC_RW2PDEN */
+                                       0x0000011e /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000005 /* EMC_TCKE */
+                                       0x00000006 /* EMC_TCKESR */
+                                       0x00000005 /* EMC_TPD */
+                                       0x0000001d /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000008 /* EMC_TCLKSTABLE */
+                                       0x00000008 /* EMC_TCLKSTOP */
+                                       0x00001822 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x80000005 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab198 /* EMC_FBIO_CFG5 */
+                                       0xe00700b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x007fc007 /* EMC_DLL_XFORM_DQS0 */
+                                       0x007fc008 /* EMC_DLL_XFORM_DQS1 */
+                                       0x007f400c /* EMC_DLL_XFORM_DQS2 */
+                                       0x007fc007 /* EMC_DLL_XFORM_DQS3 */
+                                       0x007f4006 /* EMC_DLL_XFORM_DQS4 */
+                                       0x007f8004 /* EMC_DLL_XFORM_DQS5 */
+                                       0x007f8005 /* EMC_DLL_XFORM_DQS6 */
+                                       0x007f8004 /* EMC_DLL_XFORM_DQS7 */
+                                       0x007fc007 /* EMC_DLL_XFORM_DQS8 */
+                                       0x007fc008 /* EMC_DLL_XFORM_DQS9 */
+                                       0x007f400c /* EMC_DLL_XFORM_DQS10 */
+                                       0x007fc007 /* EMC_DLL_XFORM_DQS11 */
+                                       0x007f4006 /* EMC_DLL_XFORM_DQS12 */
+                                       0x007f8004 /* EMC_DLL_XFORM_DQS13 */
+                                       0x007f8005 /* EMC_DLL_XFORM_DQS14 */
+                                       0x007f8004 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00034000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000007 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000007 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x61861820 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00492492 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00492492 /* EMC_XM2DQSPADCTRL5 */
+                                       0x61861800 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x006f000e /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000007 /* EMC_CTT */
+                                       0x00000004 /* EMC_CTT_DURATION */
+                                       0x00004080 /* EMC_CFG_PIPE */
+                                       0x80003012 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000f /* EMC_QPOP */
+                               >;
+                       };
+               };
+
+               emc-timings-6 {
+                       nvidia,ram-code = <6>;
+
+                       timing-12750000 {
+                               clock-frequency = <12750000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100003>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000000 /* EMC_RC */
+                                       0x00000003 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000000 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000060 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000018 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000007 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000005 /* EMC_TXSR */
+                                       0x00000005 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000064 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000007 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x800001c5 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-20400000 {
+                               clock-frequency = <20400000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100003>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000000 /* EMC_RC */
+                                       0x00000005 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000000 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x0000009a /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000026 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000007 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000006 /* EMC_TXSR */
+                                       0x00000006 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x000000a0 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x0000000b /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x8000023a /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-40800000 {
+                               clock-frequency = <40800000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100003>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000001 /* EMC_RC */
+                                       0x0000000a /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000001 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000134 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x0000004d /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000008 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000000c /* EMC_TXSR */
+                                       0x0000000c /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000000 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x0000013f /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000015 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x80000370 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-68000000 {
+                               clock-frequency = <68000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100003>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000003 /* EMC_RC */
+                                       0x00000011 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000002 /* EMC_RAS */
+                                       0x00000000 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000000 /* EMC_RD_RCD */
+                                       0x00000000 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000202 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000080 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x0000000f /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000013 /* EMC_TXSR */
+                                       0x00000013 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000001 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000213 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000022 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x8000050e /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-102000000 {
+                               clock-frequency = <102000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x000008c5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100003>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00000000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000004 /* EMC_RC */
+                                       0x0000001a /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000003 /* EMC_RAS */
+                                       0x00000001 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000001 /* EMC_RD_RCD */
+                                       0x00000001 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000005 /* EMC_EINPUT */
+                                       0x00000005 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000004 /* EMC_QRST */
+                                       0x0000000c /* EMC_QSAFE */
+                                       0x0000000d /* EMC_RDV */
+                                       0x0000000f /* EMC_RDV_MASK */
+                                       0x00000304 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000000c1 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000018 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000001c /* EMC_TXSR */
+                                       0x0000001c /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000003 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x0000031c /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x000fc000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000fc00 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000033 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000042 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000f2f3 /* EMC_CFG_PIPE */
+                                       0x80000713 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-204000000 {
+                               clock-frequency = <204000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                               nvidia,emc-cfg = <0x73240000>;
+                               nvidia,emc-cfg-2 = <0x0000088d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100003>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80001221>;
+                               nvidia,emc-mrs-wait-cnt = <0x000c000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0130b118>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000009 /* EMC_RC */
+                                       0x00000035 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000007 /* EMC_RAS */
+                                       0x00000002 /* EMC_RP */
+                                       0x00000005 /* EMC_R2W */
+                                       0x0000000a /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x0000000b /* EMC_W2P */
+                                       0x00000002 /* EMC_RD_RCD */
+                                       0x00000002 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000003 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000005 /* EMC_WDV */
+                                       0x00000005 /* EMC_WDV_MASK */
+                                       0x00000006 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000004 /* EMC_EINPUT */
+                                       0x00000006 /* EMC_EINPUT_DURATION */
+                                       0x00010000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000003 /* EMC_QRST */
+                                       0x0000000d /* EMC_QSAFE */
+                                       0x0000000f /* EMC_RDV */
+                                       0x00000011 /* EMC_RDV_MASK */
+                                       0x00000607 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000181 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x00000002 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000032 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x00000038 /* EMC_TXSR */
+                                       0x00000038 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000007 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000638 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x106aa298 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00064000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00004000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00090000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00090000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00094000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00094000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00009400 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00009000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000303 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x0000003f /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000066 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x000c000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x0000d2b3 /* EMC_CFG_PIPE */
+                                       0x80000d22 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000a /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-300000000 {
+                               clock-frequency = <300000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73340000>;
+                               nvidia,emc-cfg-2 = <0x000008d5>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100002>;
+                               nvidia,emc-mode-2 = <0x80200000>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80000321>;
+                               nvidia,emc-mrs-wait-cnt = <0x0174000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x0000000d /* EMC_RC */
+                                       0x0000004c /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000009 /* EMC_RAS */
+                                       0x00000003 /* EMC_RP */
+                                       0x00000004 /* EMC_R2W */
+                                       0x00000008 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x00000009 /* EMC_W2P */
+                                       0x00000003 /* EMC_RD_RCD */
+                                       0x00000003 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000005 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x00000007 /* EMC_EINPUT_DURATION */
+                                       0x00020000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x0000000e /* EMC_QSAFE */
+                                       0x00000010 /* EMC_RDV */
+                                       0x00000012 /* EMC_RDV_MASK */
+                                       0x000008e4 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000239 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000001 /* EMC_PDEX2WR */
+                                       0x00000008 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x0000004a /* EMC_AR2PDEN */
+                                       0x0000000e /* EMC_RW2PDEN */
+                                       0x00000051 /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000009 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000924 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00098000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00060000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00006000 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000096 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x0174000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000052a3 /* EMC_CFG_PIPE */
+                                       0x800012d7 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x00000009 /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-396000000 {
+                               clock-frequency = <396000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73340000>;
+                               nvidia,emc-cfg-2 = <0x00000895>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100002>;
+                               nvidia,emc-mode-2 = <0x80200000>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80000521>;
+                               nvidia,emc-mrs-wait-cnt = <0x015b000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x01231339>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000012 /* EMC_RC */
+                                       0x00000065 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x0000000c /* EMC_RAS */
+                                       0x00000004 /* EMC_RP */
+                                       0x00000005 /* EMC_R2W */
+                                       0x00000008 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x0000000a /* EMC_W2P */
+                                       0x00000004 /* EMC_RD_RCD */
+                                       0x00000004 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000005 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000001 /* EMC_EINPUT */
+                                       0x00000008 /* EMC_EINPUT_DURATION */
+                                       0x00020000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000000 /* EMC_QRST */
+                                       0x0000000f /* EMC_QSAFE */
+                                       0x00000010 /* EMC_RDV */
+                                       0x00000012 /* EMC_RDV_MASK */
+                                       0x00000bd1 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000002f4 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000001 /* EMC_PDEX2WR */
+                                       0x00000008 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000063 /* EMC_AR2PDEN */
+                                       0x0000000f /* EMC_RW2PDEN */
+                                       0x0000006b /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x0000000d /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000005 /* EMC_TCLKSTABLE */
+                                       0x00000005 /* EMC_TCLKSTOP */
+                                       0x00000c11 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0x002c00a0 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS5 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00030000 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00070000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ0 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ1 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ2 */
+                                       0x00048000 /* EMC_DLL_XFORM_DQ3 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ4 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ5 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ6 */
+                                       0x00004800 /* EMC_DLL_XFORM_DQ7 */
+                                       0x10000280 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc081 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0000003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x000000c6 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x015b000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000052a3 /* EMC_CFG_PIPE */
+                                       0x8000188b /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x00000009 /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73300000>;
+                               nvidia,emc-cfg-2 = <0x0000089d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100002>;
+                               nvidia,emc-mode-2 = <0x80200008>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80000941>;
+                               nvidia,emc-mrs-wait-cnt = <0x013a000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0123133d>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000018 /* EMC_RC */
+                                       0x00000088 /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000011 /* EMC_RAS */
+                                       0x00000006 /* EMC_RP */
+                                       0x00000006 /* EMC_R2W */
+                                       0x00000009 /* EMC_W2R */
+                                       0x00000002 /* EMC_R2P */
+                                       0x0000000d /* EMC_W2P */
+                                       0x00000006 /* EMC_RD_RCD */
+                                       0x00000006 /* EMC_WR_RCD */
+                                       0x00000002 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000003 /* EMC_WDV */
+                                       0x00000003 /* EMC_WDV_MASK */
+                                       0x00000007 /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x00000009 /* EMC_EINPUT_DURATION */
+                                       0x00040000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x00000010 /* EMC_QSAFE */
+                                       0x00000013 /* EMC_RDV */
+                                       0x00000015 /* EMC_RDV_MASK */
+                                       0x00000fd6 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000003f5 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x0000000b /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000084 /* EMC_AR2PDEN */
+                                       0x00000012 /* EMC_RW2PDEN */
+                                       0x0000008f /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000013 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000006 /* EMC_TCLKSTABLE */
+                                       0x00000006 /* EMC_TCLKSTOP */
+                                       0x00001017 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0xe01200b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS0 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS1 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS2 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS3 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS4 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS5 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS6 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS7 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS8 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS9 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS10 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS11 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS12 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS13 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS14 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00050000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000001 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000000 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000001 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x013a000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000042a0 /* EMC_CFG_PIPE */
+                                       0x80002062 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000b /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-600000000 {
+                               clock-frequency = <600000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73300000>;
+                               nvidia,emc-cfg-2 = <0x0000089d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100002>;
+                               nvidia,emc-mode-2 = <0x80200010>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80000b61>;
+                               nvidia,emc-mrs-wait-cnt = <0x0128000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040008>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0121113d>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x0000001c /* EMC_RC */
+                                       0x0000009a /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x00000013 /* EMC_RAS */
+                                       0x00000007 /* EMC_RP */
+                                       0x00000007 /* EMC_R2W */
+                                       0x0000000b /* EMC_W2R */
+                                       0x00000003 /* EMC_R2P */
+                                       0x00000010 /* EMC_W2P */
+                                       0x00000007 /* EMC_RD_RCD */
+                                       0x00000007 /* EMC_WR_RCD */
+                                       0x00000003 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000005 /* EMC_WDV */
+                                       0x00000005 /* EMC_WDV_MASK */
+                                       0x0000000a /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000003 /* EMC_EINPUT */
+                                       0x0000000b /* EMC_EINPUT_DURATION */
+                                       0x00070000 /* EMC_PUTERM_EXTRA */
+                                       0x00000003 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000002 /* EMC_QRST */
+                                       0x00000012 /* EMC_QSAFE */
+                                       0x00000016 /* EMC_RDV */
+                                       0x00000018 /* EMC_RDV_MASK */
+                                       0x00001208 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x00000482 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000002 /* EMC_PDEX2WR */
+                                       0x0000000d /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x00000096 /* EMC_AR2PDEN */
+                                       0x00000015 /* EMC_RW2PDEN */
+                                       0x000000a2 /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000004 /* EMC_TCKE */
+                                       0x00000005 /* EMC_TCKESR */
+                                       0x00000004 /* EMC_TPD */
+                                       0x00000015 /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000006 /* EMC_TCLKSTABLE */
+                                       0x00000006 /* EMC_TCLKSTOP */
+                                       0x00001249 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x00000000 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab098 /* EMC_FBIO_CFG5 */
+                                       0xe00e00b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS0 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS1 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS2 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS3 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS4 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS5 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS6 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS7 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS8 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS9 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS10 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS11 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS12 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS13 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS14 */
+                                       0x0000000a /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00048000 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000004 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000002 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000003 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000006 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x51451420 /* EMC_XM2DQSPADCTRL3 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL4 */
+                                       0x00514514 /* EMC_XM2DQSPADCTRL5 */
+                                       0x51451400 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x0128000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000000 /* EMC_CTT */
+                                       0x00000003 /* EMC_CTT_DURATION */
+                                       0x000040a0 /* EMC_CFG_PIPE */
+                                       0x800024aa /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000e /* EMC_QPOP */
+                               >;
+                       };
+
+                       timing-792000000 {
+                               clock-frequency = <792000000>;
+
+                               nvidia,emc-auto-cal-config = <0xa1430000>;
+                               nvidia,emc-auto-cal-config2 = <0x00000000>;
+                               nvidia,emc-auto-cal-config3 = <0x00000000>;
+                               nvidia,emc-auto-cal-interval = <0x001fffff>;
+                               nvidia,emc-bgbias-ctl0 = <0x00000000>;
+                               nvidia,emc-cfg = <0x73300000>;
+                               nvidia,emc-cfg-2 = <0x0080089d>;
+                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                               nvidia,emc-mode-1 = <0x80100002>;
+                               nvidia,emc-mode-2 = <0x80200418>;
+                               nvidia,emc-mode-4 = <0x00000000>;
+                               nvidia,emc-mode-reset = <0x80000d71>;
+                               nvidia,emc-mrs-wait-cnt = <0x00f8000c>;
+                               nvidia,emc-sel-dpd-ctrl = <0x00040000>;
+                               nvidia,emc-xm2dqspadctrl2 = <0x0120113d>;
+                               nvidia,emc-zcal-cnt-long = <0x00000042>;
+                               nvidia,emc-zcal-interval = <0x00020000>;
+
+                               nvidia,emc-configuration = <
+                                       0x00000025 /* EMC_RC */
+                                       0x000000cc /* EMC_RFC */
+                                       0x00000000 /* EMC_RFC_SLR */
+                                       0x0000001a /* EMC_RAS */
+                                       0x00000009 /* EMC_RP */
+                                       0x00000008 /* EMC_R2W */
+                                       0x0000000d /* EMC_W2R */
+                                       0x00000004 /* EMC_R2P */
+                                       0x00000013 /* EMC_W2P */
+                                       0x00000009 /* EMC_RD_RCD */
+                                       0x00000009 /* EMC_WR_RCD */
+                                       0x00000004 /* EMC_RRD */
+                                       0x00000002 /* EMC_REXT */
+                                       0x00000000 /* EMC_WEXT */
+                                       0x00000006 /* EMC_WDV */
+                                       0x00000006 /* EMC_WDV_MASK */
+                                       0x0000000b /* EMC_QUSE */
+                                       0x00000002 /* EMC_QUSE_WIDTH */
+                                       0x00000000 /* EMC_IBDLY */
+                                       0x00000002 /* EMC_EINPUT */
+                                       0x0000000d /* EMC_EINPUT_DURATION */
+                                       0x00080000 /* EMC_PUTERM_EXTRA */
+                                       0x00000004 /* EMC_PUTERM_WIDTH */
+                                       0x00000000 /* EMC_PUTERM_ADJ */
+                                       0x00000000 /* EMC_CDB_CNTL_1 */
+                                       0x00000000 /* EMC_CDB_CNTL_2 */
+                                       0x00000000 /* EMC_CDB_CNTL_3 */
+                                       0x00000001 /* EMC_QRST */
+                                       0x00000014 /* EMC_QSAFE */
+                                       0x00000018 /* EMC_RDV */
+                                       0x0000001a /* EMC_RDV_MASK */
+                                       0x000017e2 /* EMC_REFRESH */
+                                       0x00000000 /* EMC_BURST_REFRESH_NUM */
+                                       0x000005f8 /* EMC_PRE_REFRESH_REQ_CNT */
+                                       0x00000003 /* EMC_PDEX2WR */
+                                       0x00000011 /* EMC_PDEX2RD */
+                                       0x00000001 /* EMC_PCHG2PDEN */
+                                       0x00000000 /* EMC_ACT2PDEN */
+                                       0x000000c6 /* EMC_AR2PDEN */
+                                       0x00000018 /* EMC_RW2PDEN */
+                                       0x000000d6 /* EMC_TXSR */
+                                       0x00000200 /* EMC_TXSRDLL */
+                                       0x00000005 /* EMC_TCKE */
+                                       0x00000006 /* EMC_TCKESR */
+                                       0x00000005 /* EMC_TPD */
+                                       0x0000001d /* EMC_TFAW */
+                                       0x00000000 /* EMC_TRPAB */
+                                       0x00000008 /* EMC_TCLKSTABLE */
+                                       0x00000008 /* EMC_TCLKSTOP */
+                                       0x00001822 /* EMC_TREFBW */
+                                       0x00000000 /* EMC_FBIO_CFG6 */
+                                       0x80000005 /* EMC_ODT_WRITE */
+                                       0x00000000 /* EMC_ODT_READ */
+                                       0x104ab198 /* EMC_FBIO_CFG5 */
+                                       0xe00700b1 /* EMC_CFG_DIG_DLL */
+                                       0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */
+                                       0x00000009 /* EMC_DLL_XFORM_DQS0 */
+                                       0x00000009 /* EMC_DLL_XFORM_DQS1 */
+                                       0x00000009 /* EMC_DLL_XFORM_DQS2 */
+                                       0x00000007 /* EMC_DLL_XFORM_DQS3 */
+                                       0x00000006 /* EMC_DLL_XFORM_DQS4 */
+                                       0x00000006 /* EMC_DLL_XFORM_DQS5 */
+                                       0x007fc009 /* EMC_DLL_XFORM_DQS6 */
+                                       0x00000006 /* EMC_DLL_XFORM_DQS7 */
+                                       0x00000009 /* EMC_DLL_XFORM_DQS8 */
+                                       0x00000009 /* EMC_DLL_XFORM_DQS9 */
+                                       0x00000009 /* EMC_DLL_XFORM_DQS10 */
+                                       0x00000007 /* EMC_DLL_XFORM_DQS11 */
+                                       0x00000006 /* EMC_DLL_XFORM_DQS12 */
+                                       0x00000007 /* EMC_DLL_XFORM_DQS13 */
+                                       0x00000009 /* EMC_DLL_XFORM_DQS14 */
+                                       0x00000007 /* EMC_DLL_XFORM_DQS15 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE0 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE1 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE2 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE3 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE4 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE6 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE7 */
+                                       0x00034002 /* EMC_DLL_XFORM_ADDR0 */
+                                       0x00034002 /* EMC_DLL_XFORM_ADDR1 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                                       0x00034002 /* EMC_DLL_XFORM_ADDR3 */
+                                       0x00034002 /* EMC_DLL_XFORM_ADDR4 */
+                                       0x00000000 /* EMC_DLL_XFORM_ADDR5 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE8 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE9 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE10 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE11 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE12 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE13 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE14 */
+                                       0x00000000 /* EMC_DLL_XFORM_QUSE15 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS0 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS1 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS2 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS3 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS4 */
+                                       0x00000007 /* EMC_DLI_TRIM_TXDQS5 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS6 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS7 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS8 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS9 */
+                                       0x00000005 /* EMC_DLI_TRIM_TXDQS10 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS11 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS12 */
+                                       0x00000007 /* EMC_DLI_TRIM_TXDQS13 */
+                                       0x00000009 /* EMC_DLI_TRIM_TXDQS14 */
+                                       0x00000008 /* EMC_DLI_TRIM_TXDQS15 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ0 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ1 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ2 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ3 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ4 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ5 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ6 */
+                                       0x0000000e /* EMC_DLL_XFORM_DQ7 */
+                                       0x100002a0 /* EMC_XM2CMDPADCTRL */
+                                       0x00000000 /* EMC_XM2CMDPADCTRL4 */
+                                       0x00111111 /* EMC_XM2CMDPADCTRL5 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL2 */
+                                       0x00000000 /* EMC_XM2DQPADCTRL3 */
+                                       0x77ffc085 /* EMC_XM2CLKPADCTRL */
+                                       0x00000101 /* EMC_XM2CLKPADCTRL2 */
+                                       0x81f1f108 /* EMC_XM2COMPPADCTRL */
+                                       0x07070004 /* EMC_XM2VTTGENPADCTRL */
+                                       0x00000000 /* EMC_XM2VTTGENPADCTRL2 */
+                                       0x016eeeee /* EMC_XM2VTTGENPADCTRL3 */
+                                       0x61861820 /* EMC_XM2DQSPADCTRL3 */
+                                       0x004d34d3 /* EMC_XM2DQSPADCTRL4 */
+                                       0x004d34d3 /* EMC_XM2DQSPADCTRL5 */
+                                       0x61861800 /* EMC_XM2DQSPADCTRL6 */
+                                       0x0606003f /* EMC_DSR_VTTGEN_DRV */
+                                       0x00000000 /* EMC_TXDSRVTTGEN */
+                                       0x00000000 /* EMC_FBIO_SPARE */
+                                       0x00000100 /* EMC_ZCAL_WAIT_CNT */
+                                       0x00f8000c /* EMC_MRS_WAIT_CNT2 */
+                                       0x00000007 /* EMC_CTT */
+                                       0x00000004 /* EMC_CTT_DURATION */
+                                       0x00004080 /* EMC_CFG_PIPE */
+                                       0x80003012 /* EMC_DYN_SELF_REF_CONTROL */
+                                       0x0000000f /* EMC_QPOP */
+                               >;
+                       };
+               };
+       };
+
+       memory-controller@70019000 {
+               emc-timings-1 {
+                       nvidia,ram-code = <1>;
+
+                       timing-12750000 {
+                               clock-frequency = <12750000>;
+
+                               nvidia,emem-configuration = <
+                                       0x40040001 /* MC_EMEM_ARB_CFG */
+                                       0x8000000a /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x77e30303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-20400000 {
+                               clock-frequency = <20400000>;
+
+                               nvidia,emem-configuration = <
+                                       0x40020001 /* MC_EMEM_ARB_CFG */
+                                       0x80000012 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x76230303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-40800000 {
+                               clock-frequency = <40800000>;
+
+                               nvidia,emem-configuration = <
+                                       0xa0000001 /* MC_EMEM_ARB_CFG */
+                                       0x80000017 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x74a30303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-68000000 {
+                               clock-frequency = <68000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x00000001 /* MC_EMEM_ARB_CFG */
+                                       0x8000001e /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x74230403 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-102000000 {
+                               clock-frequency = <102000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x08000001 /* MC_EMEM_ARB_CFG */
+                                       0x80000026 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0403 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x73c30504 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-204000000 {
+                               clock-frequency = <204000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x01000003 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0405 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x73840a06 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-300000000 {
+                               clock-frequency = <300000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x08000004 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000b0607 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x77450e08 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-396000000 {
+                               clock-frequency = <396000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x0f000005 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000d0709 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x7586120a /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x0f000007 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x0000000d /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000a /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06050202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x0010090d /* MC_EMEM_ARB_DA_COVERS */
+                                       0x7428180e /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-600000000 {
+                               clock-frequency = <600000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x00000009 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x0000000e /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000b /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x0000000b /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x07050202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x00130b0e /* MC_EMEM_ARB_DA_COVERS */
+                                       0x73a91b0f /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-792000000 {
+                               clock-frequency = <792000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x0e00000b /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000013 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x0000000c /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000f /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x0000000c /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x08060202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x00160d13 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x734c2414 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f02 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+               };
+
+               emc-timings-4 {
+                       nvidia,ram-code = <4>;
+
+                       timing-12750000 {
+                               clock-frequency = <12750000>;
+
+                               nvidia,emem-configuration = <
+                                       0x40040001 /* MC_EMEM_ARB_CFG */
+                                       0x8000000a /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0502 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x77e30303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-20400000 {
+                               clock-frequency = <20400000>;
+
+                               nvidia,emem-configuration = <
+                                       0x40020001 /* MC_EMEM_ARB_CFG */
+                                       0x80000012 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0502 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x77430303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-40800000 {
+                               clock-frequency = <40800000>;
+
+                               nvidia,emem-configuration = <
+                                       0xa0000001 /* MC_EMEM_ARB_CFG */
+                                       0x80000017 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0502 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x75e30303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-68000000 {
+                               clock-frequency = <68000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x00000001 /* MC_EMEM_ARB_CFG */
+                                       0x8000001e /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0502 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x75430403 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-102000000 {
+                               clock-frequency = <102000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x08000001 /* MC_EMEM_ARB_CFG */
+                                       0x80000026 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0503 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x74e30504 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-204000000 {
+                               clock-frequency = <204000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x01000003 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0504 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x74a40a05 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-300000000 {
+                               clock-frequency = <300000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x08000004 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000b0607 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x77450e08 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-396000000 {
+                               clock-frequency = <396000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x0f000005 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000d0709 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x7586120a /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x0f000007 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x0000000c /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000a /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06050202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x0010090c /* MC_EMEM_ARB_DA_COVERS */
+                                       0x7488180d /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-600000000 {
+                               clock-frequency = <600000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x00000009 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x0000000e /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000b /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x0000000b /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x07050202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x00130b0e /* MC_EMEM_ARB_DA_COVERS */
+                                       0x74691b0f /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-792000000 {
+                               clock-frequency = <792000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x0e00000b /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000013 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x0000000c /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000f /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x0000000c /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x08060202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x00170e13 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x746c2414 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f02 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+               };
+
+               emc-timings-6 {
+                       nvidia,ram-code = <6>;
+
+                       timing-12750000 {
+                               clock-frequency = <12750000>;
+
+                               nvidia,emem-configuration = <
+                                       0x40040001 /* MC_EMEM_ARB_CFG */
+                                       0x8000000a /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x77e30303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-20400000 {
+                               clock-frequency = <20400000>;
+
+                               nvidia,emem-configuration = <
+                                       0x40020001 /* MC_EMEM_ARB_CFG */
+                                       0x80000012 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x76230303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-40800000 {
+                               clock-frequency = <40800000>;
+
+                               nvidia,emem-configuration = <
+                                       0xa0000001 /* MC_EMEM_ARB_CFG */
+                                       0x80000017 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x74a30303 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-68000000 {
+                               clock-frequency = <68000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x00000001 /* MC_EMEM_ARB_CFG */
+                                       0x8000001e /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0402 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x74230403 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-102000000 {
+                               clock-frequency = <102000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x08000001 /* MC_EMEM_ARB_CFG */
+                                       0x80000026 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000000 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06030203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0403 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x73c30504 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-204000000 {
+                               clock-frequency = <204000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x01000003 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040203 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000a0405 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x73840a06 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-300000000 {
+                               clock-frequency = <300000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x08000004 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000b0607 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x77450e08 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-396000000 {
+                               clock-frequency = <396000000>;
+
+                               nvidia,emem-configuration = <
+                                       0x0f000005 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06040202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x000d0709 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x7586120a /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
+                               >;
+                       };
+
+                       timing-528000000 {
+                               clock-frequency = <528000000>;
 
                                nvidia,emem-configuration = <
-                                       0x0f000005
-                                       0x80000040
-                                       0x00000001
-                                       0x00000002
-                                       0x00000009
-                                       0x00000005
-                                       0x00000007
-                                       0x00000001
-                                       0x00000002
-                                       0x00000008
-                                       0x00000002
-                                       0x00000002
-                                       0x00000004
-                                       0x00000006
-                                       0x06040202
-                                       0x000d0709
-                                       0x7586120a
-                                       0x70000f03
-                                       0x001f0000
+                                       0x0f000007 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x0000000d /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000a /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000001 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x06050202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x0010090d /* MC_EMEM_ARB_DA_COVERS */
+                                       0x7428180e /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
                                >;
                        };
 
                                clock-frequency = <600000000>;
 
                                nvidia,emem-configuration = <
-                                       0x00000009
-                                       0x80000040
-                                       0x00000003
-                                       0x00000004
-                                       0x0000000e
-                                       0x00000009
-                                       0x0000000b
-                                       0x00000001
-                                       0x00000003
-                                       0x0000000b
-                                       0x00000002
-                                       0x00000002
-                                       0x00000005
-                                       0x00000007
-                                       0x07050202
-                                       0x00130b0e
-                                       0x73a91b0f
-                                       0x70000f03
-                                       0x001f0000
+                                       0x00000009 /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x0000000e /* MC_EMEM_ARB_TIMING_RC */
+                                       0x00000009 /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000b /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x0000000b /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000007 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x07050202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x00130b0e /* MC_EMEM_ARB_DA_COVERS */
+                                       0x73a91b0f /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f03 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
                                >;
                        };
 
                                clock-frequency = <792000000>;
 
                                nvidia,emem-configuration = <
-                                       0x0e00000b
-                                       0x80000040
-                                       0x00000004
-                                       0x00000005
-                                       0x00000013
-                                       0x0000000c
-                                       0x0000000f
-                                       0x00000002
-                                       0x00000003
-                                       0x0000000c
-                                       0x00000002
-                                       0x00000002
-                                       0x00000006
-                                       0x00000008
-                                       0x08060202
-                                       0x00160d13
-                                       0x734c2414
-                                       0x70000f02
-                                       0x001f0000
+                                       0x0e00000b /* MC_EMEM_ARB_CFG */
+                                       0x80000040 /* MC_EMEM_ARB_OUTSTANDING_REQ */
+                                       0x00000004 /* MC_EMEM_ARB_TIMING_RCD */
+                                       0x00000005 /* MC_EMEM_ARB_TIMING_RP */
+                                       0x00000013 /* MC_EMEM_ARB_TIMING_RC */
+                                       0x0000000c /* MC_EMEM_ARB_TIMING_RAS */
+                                       0x0000000f /* MC_EMEM_ARB_TIMING_FAW */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_RRD */
+                                       0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */
+                                       0x0000000c /* MC_EMEM_ARB_TIMING_WAP2PRE */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_R2R */
+                                       0x00000002 /* MC_EMEM_ARB_TIMING_W2W */
+                                       0x00000006 /* MC_EMEM_ARB_TIMING_R2W */
+                                       0x00000008 /* MC_EMEM_ARB_TIMING_W2R */
+                                       0x08060202 /* MC_EMEM_ARB_DA_TURNS */
+                                       0x00160d13 /* MC_EMEM_ARB_DA_COVERS */
+                                       0x734c2414 /* MC_EMEM_ARB_MISC0 */
+                                       0x70000f02 /* MC_EMEM_ARB_MISC1 */
+                                       0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */
                                >;
                        };
                };
index 5d5e6e1..7309393 100644 (file)
@@ -38,6 +38,9 @@
                sor@54540000 {
                        status = "okay";
 
+                       avdd-io-hdmi-dp-supply = <&vdd_1v05_run>;
+                       vdd-hdmi-dp-pll-supply = <&vdd_3v3_run>;
+
                        nvidia,dpaux = <&dpaux>;
                        nvidia,panel = <&panel>;
                };
index b113e47..413bfb9 100644 (file)
                        reg = <0x0 0x54540000 0x0 0x00040000>;
                        interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&tegra_car TEGRA124_CLK_SOR0>,
+                                <&tegra_car TEGRA124_CLK_SOR0_OUT>,
                                 <&tegra_car TEGRA124_CLK_PLL_D_OUT0>,
                                 <&tegra_car TEGRA124_CLK_PLL_DP>,
                                 <&tegra_car TEGRA124_CLK_CLK_M>;
-                       clock-names = "sor", "parent", "dp", "safe";
+                       clock-names = "sor", "out", "parent", "dp", "safe";
                        resets = <&tegra_car 182>;
                        reset-names = "sor";
                        status = "disabled";
diff --git a/arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi b/arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi
new file mode 100644 (file)
index 0000000..e85ffdb
--- /dev/null
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+       cpu0_opp_table: cpu_opp_table0 {
+               opp@216000000_750 {
+                       opp-microvolt = <750000 750000 1125000>;
+               };
+
+               opp@216000000_800 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@312000000_750 {
+                       opp-microvolt = <750000 750000 1125000>;
+               };
+
+               opp@312000000_800 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@456000000_750 {
+                       opp-microvolt = <750000 750000 1125000>;
+               };
+
+               opp@456000000_800 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@456000000_800_2_2 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@456000000_800_3_2 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@456000000_825 {
+                       opp-microvolt = <825000 825000 1125000>;
+               };
+
+               opp@608000000_750 {
+                       opp-microvolt = <750000 750000 1125000>;
+               };
+
+               opp@608000000_800 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@608000000_800_3_2 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@608000000_825 {
+                       opp-microvolt = <825000 825000 1125000>;
+               };
+
+               opp@608000000_850 {
+                       opp-microvolt = <850000 850000 1125000>;
+               };
+
+               opp@608000000_900 {
+                       opp-microvolt = <900000 900000 1125000>;
+               };
+
+               opp@760000000_775 {
+                       opp-microvolt = <775000 775000 1125000>;
+               };
+
+               opp@760000000_800 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@760000000_850 {
+                       opp-microvolt = <850000 850000 1125000>;
+               };
+
+               opp@760000000_875 {
+                       opp-microvolt = <875000 875000 1125000>;
+               };
+
+               opp@760000000_875_1_1 {
+                       opp-microvolt = <875000 875000 1125000>;
+               };
+
+               opp@760000000_875_0_2 {
+                       opp-microvolt = <875000 875000 1125000>;
+               };
+
+               opp@760000000_875_1_2 {
+                       opp-microvolt = <875000 875000 1125000>;
+               };
+
+               opp@760000000_900 {
+                       opp-microvolt = <900000 900000 1125000>;
+               };
+
+               opp@760000000_975 {
+                       opp-microvolt = <975000 975000 1125000>;
+               };
+
+               opp@816000000_800 {
+                       opp-microvolt = <800000 800000 1125000>;
+               };
+
+               opp@816000000_850 {
+                       opp-microvolt = <850000 850000 1125000>;
+               };
+
+               opp@816000000_875 {
+                       opp-microvolt = <875000 875000 1125000>;
+               };
+
+               opp@816000000_950 {
+                       opp-microvolt = <950000 950000 1125000>;
+               };
+
+               opp@816000000_1000 {
+                       opp-microvolt = <1000000 1000000 1125000>;
+               };
+
+               opp@912000000_850 {
+                       opp-microvolt = <850000 850000 1125000>;
+               };
+
+               opp@912000000_900 {
+                       opp-microvolt = <900000 900000 1125000>;
+               };
+
+               opp@912000000_925 {
+                       opp-microvolt = <925000 925000 1125000>;
+               };
+
+               opp@912000000_950 {
+                       opp-microvolt = <950000 950000 1125000>;
+               };
+
+               opp@912000000_950_0_2 {
+                       opp-microvolt = <950000 950000 1125000>;
+               };
+
+               opp@912000000_950_2_2 {
+                       opp-microvolt = <950000 950000 1125000>;
+               };
+
+               opp@912000000_1000 {
+                       opp-microvolt = <1000000 1000000 1125000>;
+               };
+
+               opp@912000000_1050 {
+                       opp-microvolt = <1050000 1050000 1125000>;
+               };
+
+               opp@1000000000_875 {
+                       opp-microvolt = <875000 875000 1125000>;
+               };
+
+               opp@1000000000_900 {
+                       opp-microvolt = <900000 900000 1125000>;
+               };
+
+               opp@1000000000_950 {
+                       opp-microvolt = <950000 950000 1125000>;
+               };
+
+               opp@1000000000_975 {
+                       opp-microvolt = <975000 975000 1125000>;
+               };
+
+               opp@1000000000_1000 {
+                       opp-microvolt = <1000000 1000000 1125000>;
+               };
+
+               opp@1000000000_1000_0_2 {
+                       opp-microvolt = <1000000 1000000 1125000>;
+               };
+
+               opp@1000000000_1025 {
+                       opp-microvolt = <1025000 1025000 1125000>;
+               };
+
+               opp@1000000000_1100 {
+                       opp-microvolt = <1100000 1100000 1125000>;
+               };
+
+               opp@1200000000_1000 {
+                       opp-microvolt = <1000000 1000000 1125000>;
+               };
+
+               opp@1200000000_1050 {
+                       opp-microvolt = <1050000 1050000 1125000>;
+               };
+
+               opp@1200000000_1100 {
+                       opp-microvolt = <1100000 1100000 1125000>;
+               };
+
+               opp@1200000000_1125 {
+                       opp-microvolt = <1125000 1125000 1125000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/tegra20-cpu-opp.dtsi b/arch/arm/boot/dts/tegra20-cpu-opp.dtsi
new file mode 100644 (file)
index 0000000..c878f42
--- /dev/null
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+       cpu0_opp_table: cpu_opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp@216000000_750 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x0F 0x0003>;
+                       opp-hz = /bits/ 64 <216000000>;
+               };
+
+               opp@216000000_800 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x0F 0x0004>;
+                       opp-hz = /bits/ 64 <216000000>;
+               };
+
+               opp@312000000_750 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x0F 0x0003>;
+                       opp-hz = /bits/ 64 <312000000>;
+               };
+
+               opp@312000000_800 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x0F 0x0004>;
+                       opp-hz = /bits/ 64 <312000000>;
+               };
+
+               opp@456000000_750 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x0C 0x0003>;
+                       opp-hz = /bits/ 64 <456000000>;
+               };
+
+               opp@456000000_800 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0006>;
+                       opp-hz = /bits/ 64 <456000000>;
+               };
+
+               opp@456000000_800_2_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <456000000>;
+               };
+
+               opp@456000000_800_3_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <456000000>;
+               };
+
+               opp@456000000_825 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0001>;
+                       opp-hz = /bits/ 64 <456000000>;
+               };
+
+               opp@608000000_750 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0003>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@608000000_800 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0006>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@608000000_800_3_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@608000000_825 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0001>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@608000000_850 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0006>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@608000000_900 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0001>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@760000000_775 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0003>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_800 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0006>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_875 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0001>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_875_1_1 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x02 0x0002>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_875_0_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x01 0x0004>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_875_1_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x02 0x0004>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x01 0x0002>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_975 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0001>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@816000000_800 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0007>;
+                       opp-hz = /bits/ 64 <816000000>;
+               };
+
+               opp@816000000_850 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <816000000>;
+               };
+
+               opp@816000000_875 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0005>;
+                       opp-hz = /bits/ 64 <816000000>;
+               };
+
+               opp@816000000_950 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0006>;
+                       opp-hz = /bits/ 64 <816000000>;
+               };
+
+               opp@816000000_1000 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0001>;
+                       opp-hz = /bits/ 64 <816000000>;
+               };
+
+               opp@912000000_850 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0007>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@912000000_900 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@912000000_925 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0001>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@912000000_950 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x02 0x0006>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@912000000_950_0_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x01 0x0004>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@912000000_950_2_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@912000000_1000 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x01 0x0002>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@912000000_1050 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0001>;
+                       opp-hz = /bits/ 64 <912000000>;
+               };
+
+               opp@1000000000_875 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0007>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_900 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_950 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0001>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_1000 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x02 0x0006>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_1000_0_2 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x01 0x0004>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_1025 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x01 0x0002>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_1100 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x03 0x0001>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1200000000_1000 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1050 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1100 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x02 0x0004>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1125 {
+                       clock-latency-ns = <400000>;
+                       opp-supported-hw = <0x01 0x0004>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+       };
+};
index 8861e09..85fce5b 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <dt-bindings/input/input.h>
 #include "tegra20.dtsi"
+#include "tegra20-cpu-opp.dtsi"
+#include "tegra20-cpu-opp-microvolt.dtsi"
 
 / {
        model = "Toshiba AC100 / Dynabook AZ";
                                        regulator-always-on;
                                };
 
-                               sm0 {
+                               core_vdd_reg: sm0 {
                                        regulator-name = "+1.2vs_sm0,vdd_core";
                                        regulator-min-microvolt = <1200000>;
-                                       regulator-max-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1225000>;
+                                       regulator-coupled-with = <&rtc_vdd_reg &cpu_vdd_reg>;
+                                       regulator-coupled-max-spread = <170000 450000>;
                                        regulator-always-on;
+
+                                       nvidia,tegra-core-regulator;
                                };
 
-                               sm1 {
+                               cpu_vdd_reg: sm1 {
                                        regulator-name = "+1.0vs_sm1,vdd_cpu";
-                                       regulator-min-microvolt = <1000000>;
-                                       regulator-max-microvolt = <1000000>;
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-coupled-with = <&core_vdd_reg &rtc_vdd_reg>;
+                                       regulator-coupled-max-spread = <450000 450000>;
                                        regulator-always-on;
+
+                                       nvidia,tegra-cpu-regulator;
                                };
 
                                sm2_reg: sm2 {
                                        regulator-always-on;
                                };
 
-                               ldo2 {
+                               rtc_vdd_reg: ldo2 {
                                        regulator-name = "+1.2vs_ldo2,vdd_rtc";
                                        regulator-min-microvolt = <1200000>;
-                                       regulator-max-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1225000>;
+                                       regulator-coupled-with = <&core_vdd_reg &cpu_vdd_reg>;
+                                       regulator-coupled-max-spread = <170000 450000>;
+                                       regulator-always-on;
+
+                                       nvidia,tegra-rtc-regulator;
                                };
 
                                ldo3 {
                         <&tegra_car TEGRA20_CLK_CDEV1>;
                clock-names = "pll_a", "pll_a_out0", "mclk";
        };
+
+       cpus {
+               cpu0: cpu@0 {
+                       cpu-supply = <&cpu_vdd_reg>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu@1 {
+                       cpu-supply = <&cpu_vdd_reg>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+       };
 };
index 3e5ac09..8debd3d 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <dt-bindings/input/input.h>
 #include "tegra20.dtsi"
+#include "tegra20-cpu-opp.dtsi"
 
 / {
        model = "Compulab TrimSlice board";
                         <&tegra_car TEGRA20_CLK_CDEV1>;
                clock-names = "pll_a", "pll_a_out0", "mclk";
        };
+
+       cpus {
+               cpu0: cpu@0 {
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu@1 {
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+       };
 };
index 8c942e6..9c58e7f 100644 (file)
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0>;
+                       clocks = <&tegra_car TEGRA20_CLK_CCLK>;
                };
 
                cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <1>;
+                       clocks = <&tegra_car TEGRA20_CLK_CCLK>;
                };
        };
 
index 02f8126..8b7a827 100644 (file)
                        id = <0>;
                        blocks = <0x5>;
                        irq-trigger = <0x1>;
+                       /* 3.25 MHz ADC clock speed */
+                       st,adc-freq = <1>;
+                       /* 12-bit ADC */
+                       st,mod-12b = <1>;
+                       /* internal ADC reference */
+                       st,ref-sel = <0>;
+                       /* ADC converstion time: 80 clocks */
+                       st,sample-time = <4>;
 
                        stmpe_touchscreen {
                                compatible = "st,stmpe-ts";
-                               /* 3.25 MHz ADC clock speed */
-                               st,adc-freq = <1>;
                                /* 8 sample average control */
                                st,ave-ctrl = <3>;
                                /* 7 length fractional part in z */
                                 * 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>;
                        };
+
+                       stmpe_adc {
+                               compatible = "st,stmpe-adc";
+                               /* forbid to use ADC channels 3-0 (touch) */
+                               st,norequest-mask = <0x0F>;
+                       };
                };
 
                /*
index 7f112f1..c18f6f6 100644 (file)
                        id = <0>;
                        blocks = <0x5>;
                        irq-trigger = <0x1>;
+                       /* 3.25 MHz ADC clock speed */
+                       st,adc-freq = <1>;
+                       /* 12-bit ADC */
+                       st,mod-12b = <1>;
+                       /* internal ADC reference */
+                       st,ref-sel = <0>;
+                       /* ADC converstion time: 80 clocks */
+                       st,sample-time = <4>;
 
                        stmpe_touchscreen {
                                compatible = "st,stmpe-ts";
-                               /* 3.25 MHz ADC clock speed */
-                               st,adc-freq = <1>;
                                /* 8 sample average control */
                                st,ave-ctrl = <3>;
                                /* 7 length fractional part in z */
                                 * 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>;
                        };
+
+                       stmpe_adc {
+                               compatible = "st,stmpe-adc";
+                               /* forbid to use ADC channels 3-0 (touch) */
+                               st,norequest-mask = <0x0F>;
+                       };
                };
 
                /*
index 4dbd4af..9234988 100644 (file)
@@ -2,6 +2,8 @@
 /dts-v1/;
 
 #include "tegra30-cardhu.dtsi"
+#include "tegra30-cpu-opp.dtsi"
+#include "tegra30-cpu-opp-microvolt.dtsi"
 
 /* This dts file support the cardhu A04 and later versions of board */
 
                        gpio = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_HIGH>;
                };
        };
+
+       i2c@7000d000 {
+               pmic: tps65911@2d {
+                       regulators {
+                               vddctrl_reg: vddctrl {
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1125000>;
+                                       regulator-coupled-with = <&vddcore_reg>;
+                                       regulator-coupled-max-spread = <300000>;
+                                       regulator-max-step-microvolt = <100000>;
+
+                                       nvidia,tegra-cpu-regulator;
+                               };
+                       };
+               };
+
+               vddcore_reg: tps62361@60 {
+                       regulator-coupled-with = <&vddctrl_reg>;
+                       regulator-coupled-max-spread = <300000>;
+                       regulator-max-step-microvolt = <100000>;
+
+                       nvidia,tegra-core-regulator;
+               };
+       };
+
+       cpus {
+               cpu0: cpu@0 {
+                       cpu-supply = <&vddctrl_reg>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu@1 {
+                       cpu-supply = <&vddctrl_reg>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu@2 {
+                       cpu-supply = <&vddctrl_reg>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu@3 {
+                       cpu-supply = <&vddctrl_reg>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+       };
 };
index 35af03c..1f9198b 100644 (file)
                        id = <0>;
                        blocks = <0x5>;
                        irq-trigger = <0x1>;
+                       /* 3.25 MHz ADC clock speed */
+                       st,adc-freq = <1>;
+                       /* 12-bit ADC */
+                       st,mod-12b = <1>;
+                       /* internal ADC reference */
+                       st,ref-sel = <0>;
+                       /* ADC converstion time: 80 clocks */
+                       st,sample-time = <4>;
+                       /* forbid to use ADC channels 3-0 (touch) */
 
                        stmpe_touchscreen {
                                compatible = "st,stmpe-ts";
-                               /* 3.25 MHz ADC clock speed */
-                               st,adc-freq = <1>;
                                /* 8 sample average control */
                                st,ave-ctrl = <3>;
                                /* 7 length fractional part in z */
                                 * 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>;
                        };
+
+                       stmpe_adc {
+                               compatible = "st,stmpe-adc";
+                               st,norequest-mask = <0x0F>;
+                       };
                };
 
                /*
diff --git a/arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi b/arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi
new file mode 100644 (file)
index 0000000..5c40ef4
--- /dev/null
@@ -0,0 +1,801 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+       cpu0_opp_table: cpu_opp_table0 {
+               opp@51000000_800 {
+                       opp-microvolt = <800000 800000 1250000>;
+               };
+
+               opp@51000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@51000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@102000000_800 {
+                       opp-microvolt = <800000 800000 1250000>;
+               };
+
+               opp@102000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@102000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@204000000_800 {
+                       opp-microvolt = <800000 800000 1250000>;
+               };
+
+               opp@204000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@204000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@312000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@312000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@340000000_800 {
+                       opp-microvolt = <800000 800000 1250000>;
+               };
+
+               opp@340000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@370000000_800 {
+                       opp-microvolt = <800000 800000 1250000>;
+               };
+
+               opp@456000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@456000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@475000000_800 {
+                       opp-microvolt = <800000 800000 1250000>;
+               };
+
+               opp@475000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@475000000_850_0_1 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@475000000_850_0_4 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@475000000_850_0_7 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@475000000_850_0_8 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@608000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@608000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@620000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_1_1 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_2_1 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_3_1 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_1_4 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_2_4 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_3_4 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_1_7 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_2_7 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_3_7 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_4_7 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_1_8 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_2_8 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_3_8 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_850_4_8 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@640000000_900 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_3_1 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_3_2 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_3_3 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_3_4 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_3_7 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_4_7 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_3_8 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_4_8 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_850_0_10 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@760000000_900 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_1_1 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_2_1 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_1_2 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_2_2 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_1_3 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_2_3 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_1_4 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_2_4 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_1_7 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_2_7 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_1_8 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_900_2_8 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@760000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@760000000_975 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@816000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@816000000_912 {
+                       opp-microvolt = <912000 912000 1250000>;
+               };
+
+               opp@860000000_850 {
+                       opp-microvolt = <850000 850000 1250000>;
+               };
+
+               opp@860000000_900 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_2_1 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_3_1 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_2_2 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_3_2 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_2_3 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_3_3 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_2_4 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_3_4 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_2_7 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_3_7 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_4_7 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_2_8 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_3_8 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_900_4_8 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@860000000_975 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@860000000_975_1_1 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@860000000_975_1_2 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@860000000_975_1_3 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@860000000_975_1_4 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@860000000_975_1_7 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@860000000_975_1_8 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@860000000_1000 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@910000000_900 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@1000000000_900 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@1000000000_975 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_2_1 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_3_1 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_2_2 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_3_2 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_2_3 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_3_3 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_2_4 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_3_4 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_2_7 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_3_7 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_4_7 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_2_8 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_3_8 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_975_4_8 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1000000000_1000 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1000000000_1025 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1100000000_900 {
+                       opp-microvolt = <900000 900000 1250000>;
+               };
+
+               opp@1100000000_975 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_3_1 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_3_2 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_3_3 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_3_4 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_3_7 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_4_7 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_3_8 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_975_4_8 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1100000000_1000 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1100000000_1000_2_1 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1100000000_1000_2_2 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1100000000_1000_2_3 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1100000000_1000_2_4 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1100000000_1000_2_7 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1100000000_1000_2_8 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1100000000_1025 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1100000000_1075 {
+                       opp-microvolt = <1075000 1075000 1250000>;
+               };
+
+               opp@1150000000_975 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1200000000_975 {
+                       opp-microvolt = <975000 975000 1250000>;
+               };
+
+               opp@1200000000_1000 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_3_1 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_3_2 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_3_3 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_3_4 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_3_7 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_4_7 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_3_8 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1000_4_8 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1200000000_1025 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1200000000_1025_2_1 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1200000000_1025_2_2 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1200000000_1025_2_3 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1200000000_1025_2_4 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1200000000_1025_2_7 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1200000000_1025_2_8 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1200000000_1050 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1200000000_1075 {
+                       opp-microvolt = <1075000 1075000 1250000>;
+               };
+
+               opp@1200000000_1100 {
+                       opp-microvolt = <1100000 1100000 1250000>;
+               };
+
+               opp@1300000000_1000 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1300000000_1000_4_7 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1300000000_1000_4_8 {
+                       opp-microvolt = <1000000 1000000 1250000>;
+               };
+
+               opp@1300000000_1025 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1300000000_1025_3_1 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1300000000_1025_3_7 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1300000000_1025_3_8 {
+                       opp-microvolt = <1025000 1025000 1250000>;
+               };
+
+               opp@1300000000_1050 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_2_1 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_3_2 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_3_3 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_3_4 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_3_5 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_3_6 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_2_7 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_2_8 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_3_12 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1050_3_13 {
+                       opp-microvolt = <1050000 1050000 1250000>;
+               };
+
+               opp@1300000000_1075 {
+                       opp-microvolt = <1075000 1075000 1250000>;
+               };
+
+               opp@1300000000_1075_2_2 {
+                       opp-microvolt = <1075000 1075000 1250000>;
+               };
+
+               opp@1300000000_1075_2_3 {
+                       opp-microvolt = <1075000 1075000 1250000>;
+               };
+
+               opp@1300000000_1075_2_4 {
+                       opp-microvolt = <1075000 1075000 1250000>;
+               };
+
+               opp@1300000000_1100 {
+                       opp-microvolt = <1100000 1100000 1250000>;
+               };
+
+               opp@1300000000_1125 {
+                       opp-microvolt = <1125000 1125000 1250000>;
+               };
+
+               opp@1300000000_1150 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1300000000_1175 {
+                       opp-microvolt = <1175000 1175000 1250000>;
+               };
+
+               opp@1400000000_1100 {
+                       opp-microvolt = <1100000 1100000 1250000>;
+               };
+
+               opp@1400000000_1125 {
+                       opp-microvolt = <1125000 1125000 1250000>;
+               };
+
+               opp@1400000000_1150 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1400000000_1150_2_4 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1400000000_1175 {
+                       opp-microvolt = <1175000 1175000 1250000>;
+               };
+
+               opp@1400000000_1237 {
+                       opp-microvolt = <1237000 1237000 1250000>;
+               };
+
+               opp@1500000000_1125 {
+                       opp-microvolt = <1125000 1125000 1250000>;
+               };
+
+               opp@1500000000_1125_4_5 {
+                       opp-microvolt = <1125000 1125000 1250000>;
+               };
+
+               opp@1500000000_1125_4_6 {
+                       opp-microvolt = <1125000 1125000 1250000>;
+               };
+
+               opp@1500000000_1125_4_12 {
+                       opp-microvolt = <1125000 1125000 1250000>;
+               };
+
+               opp@1500000000_1125_4_13 {
+                       opp-microvolt = <1125000 1125000 1250000>;
+               };
+
+               opp@1500000000_1150 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1500000000_1150_3_5 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1500000000_1150_3_6 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1500000000_1150_3_12 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1500000000_1150_3_13 {
+                       opp-microvolt = <1150000 1150000 1250000>;
+               };
+
+               opp@1500000000_1200 {
+                       opp-microvolt = <1200000 1200000 1250000>;
+               };
+
+               opp@1500000000_1237 {
+                       opp-microvolt = <1237000 1237000 1250000>;
+               };
+
+               opp@1600000000_1212 {
+                       opp-microvolt = <1212000 1212000 1250000>;
+               };
+
+               opp@1600000000_1237 {
+                       opp-microvolt = <1237000 1237000 1250000>;
+               };
+
+               opp@1700000000_1212 {
+                       opp-microvolt = <1212000 1212000 1250000>;
+               };
+
+               opp@1700000000_1237 {
+                       opp-microvolt = <1237000 1237000 1250000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/tegra30-cpu-opp.dtsi b/arch/arm/boot/dts/tegra30-cpu-opp.dtsi
new file mode 100644 (file)
index 0000000..d64fc26
--- /dev/null
@@ -0,0 +1,1202 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+       cpu0_opp_table: cpu_opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp@51000000_800 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x31FE>;
+                       opp-hz = /bits/ 64 <51000000>;
+               };
+
+               opp@51000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0C01>;
+                       opp-hz = /bits/ 64 <51000000>;
+               };
+
+               opp@51000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <51000000>;
+               };
+
+               opp@102000000_800 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x31FE>;
+                       opp-hz = /bits/ 64 <102000000>;
+               };
+
+               opp@102000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0C01>;
+                       opp-hz = /bits/ 64 <102000000>;
+               };
+
+               opp@102000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <102000000>;
+               };
+
+               opp@204000000_800 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x31FE>;
+                       opp-hz = /bits/ 64 <204000000>;
+               };
+
+               opp@204000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0C01>;
+                       opp-hz = /bits/ 64 <204000000>;
+               };
+
+               opp@204000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <204000000>;
+               };
+
+               opp@312000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0C00>;
+                       opp-hz = /bits/ 64 <312000000>;
+               };
+
+               opp@312000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <312000000>;
+               };
+
+               opp@340000000_800 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0192>;
+                       opp-hz = /bits/ 64 <340000000>;
+               };
+
+               opp@340000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x0F 0x0001>;
+                       opp-hz = /bits/ 64 <340000000>;
+               };
+
+               opp@370000000_800 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1E 0x306C>;
+                       opp-hz = /bits/ 64 <370000000>;
+               };
+
+               opp@456000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0C00>;
+                       opp-hz = /bits/ 64 <456000000>;
+               };
+
+               opp@456000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <456000000>;
+               };
+
+               opp@475000000_800 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1E 0x31FE>;
+                       opp-hz = /bits/ 64 <475000000>;
+               };
+
+               opp@475000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x0F 0x0001>;
+                       opp-hz = /bits/ 64 <475000000>;
+               };
+
+               opp@475000000_850_0_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0002>;
+                       opp-hz = /bits/ 64 <475000000>;
+               };
+
+               opp@475000000_850_0_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0010>;
+                       opp-hz = /bits/ 64 <475000000>;
+               };
+
+               opp@475000000_850_0_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0080>;
+                       opp-hz = /bits/ 64 <475000000>;
+               };
+
+               opp@475000000_850_0_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0100>;
+                       opp-hz = /bits/ 64 <475000000>;
+               };
+
+               opp@608000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0400>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@608000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <608000000>;
+               };
+
+               opp@620000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1E 0x306C>;
+                       opp-hz = /bits/ 64 <620000000>;
+               };
+
+               opp@640000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x0F 0x0001>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_1_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0002>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_2_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_3_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0002>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_1_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0010>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_3_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_1_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0080>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_2_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0080>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_3_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0080>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_4_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0080>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_1_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0100>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_2_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0100>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_3_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0100>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_850_4_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0100>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@640000000_900 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0192>;
+                       opp-hz = /bits/ 64 <640000000>;
+               };
+
+               opp@760000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1E 0x3461>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_3_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0002>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_3_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_3_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0008>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_3_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_3_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0080>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_4_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0080>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_3_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0100>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_4_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0100>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_850_0_10 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0400>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0001>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_1_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0002>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_2_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_1_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0004>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_2_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_1_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0008>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_2_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0008>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_1_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0010>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_1_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0080>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_2_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0080>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_1_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0100>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_900_2_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0100>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@760000000_975 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0192>;
+                       opp-hz = /bits/ 64 <760000000>;
+               };
+
+               opp@816000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0400>;
+                       opp-hz = /bits/ 64 <816000000>;
+               };
+
+               opp@816000000_912 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x1F 0x0200>;
+                       opp-hz = /bits/ 64 <816000000>;
+               };
+
+               opp@860000000_850 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x0C 0x0001>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0001>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_2_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_3_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0002>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_2_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_3_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_2_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0008>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_3_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0008>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_3_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_2_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0080>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_3_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0080>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_4_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0080>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_2_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0100>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_3_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0100>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_900_4_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0100>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_975 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0001>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_975_1_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0002>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_975_1_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0004>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_975_1_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0008>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_975_1_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0010>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_975_1_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0080>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_975_1_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0100>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@860000000_1000 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0192>;
+                       opp-hz = /bits/ 64 <860000000>;
+               };
+
+               opp@910000000_900 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x18 0x3060>;
+                       opp-hz = /bits/ 64 <910000000>;
+               };
+
+               opp@1000000000_900 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x0C 0x0001>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x03 0x0001>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_2_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_3_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0002>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_2_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_3_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_2_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0008>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_3_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0008>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_3_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_2_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0080>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_3_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0080>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_4_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0080>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_2_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0100>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_3_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0100>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_975_4_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0100>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_1000 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x019E>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1000000000_1025 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0192>;
+                       opp-hz = /bits/ 64 <1000000000>;
+               };
+
+               opp@1100000000_900 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0001>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x06 0x0001>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_3_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0002>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_3_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_3_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0008>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_3_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_3_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0080>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_4_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0080>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_3_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0100>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_975_4_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0100>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1000 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0001>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1000_2_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1000_2_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1000_2_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0008>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1000_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1000_2_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0080>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1000_2_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0100>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1025 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x019E>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1100000000_1075 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0192>;
+                       opp-hz = /bits/ 64 <1100000000>;
+               };
+
+               opp@1150000000_975 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x18 0x3060>;
+                       opp-hz = /bits/ 64 <1150000000>;
+               };
+
+               opp@1200000000_975 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0001>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0001>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_3_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0002>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_3_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_3_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0008>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_3_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_3_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0080>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_4_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0080>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_3_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0100>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1000_4_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0100>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1025 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0001>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1025_2_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1025_2_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1025_2_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0008>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1025_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1025_2_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0080>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1025_2_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0100>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1050 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x019E>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1075 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0001>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1200000000_1100 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0192>;
+                       opp-hz = /bits/ 64 <1200000000>;
+               };
+
+               opp@1300000000_1000 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0001>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1000_4_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0080>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1000_4_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0100>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1025 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0001>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1025_3_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0002>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1025_3_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0080>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1025_3_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0100>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x12 0x3061>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_2_1 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0002>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_3_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0004>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_3_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0008>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_3_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_3_5 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0020>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_3_6 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0040>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_2_7 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0080>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_2_8 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0100>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_3_12 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x1000>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1050_3_13 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x2000>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1075 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0182>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1075_2_2 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0004>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1075_2_3 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0008>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1075_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1100 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x001C>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1125 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0001>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1150 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0182>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1300000000_1175 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0010>;
+                       opp-hz = /bits/ 64 <1300000000>;
+               };
+
+               opp@1400000000_1100 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x18 0x307C>;
+                       opp-hz = /bits/ 64 <1400000000>;
+               };
+
+               opp@1400000000_1125 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x000C>;
+                       opp-hz = /bits/ 64 <1400000000>;
+               };
+
+               opp@1400000000_1150 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x000C>;
+                       opp-hz = /bits/ 64 <1400000000>;
+               };
+
+               opp@1400000000_1150_2_4 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <1400000000>;
+               };
+
+               opp@1400000000_1175 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0010>;
+                       opp-hz = /bits/ 64 <1400000000>;
+               };
+
+               opp@1400000000_1237 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0010>;
+                       opp-hz = /bits/ 64 <1400000000>;
+               };
+
+               opp@1500000000_1125 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0010>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1125_4_5 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0020>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1125_4_6 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x0040>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1125_4_12 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x1000>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1125_4_13 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x2000>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1150 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x04 0x0010>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1150_3_5 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0020>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1150_3_6 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x0040>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1150_3_12 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x1000>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1150_3_13 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x2000>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1200 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x02 0x0010>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1500000000_1237 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x01 0x0010>;
+                       opp-hz = /bits/ 64 <1500000000>;
+               };
+
+               opp@1600000000_1212 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x3060>;
+                       opp-hz = /bits/ 64 <1600000000>;
+               };
+
+               opp@1600000000_1237 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x3060>;
+                       opp-hz = /bits/ 64 <1600000000>;
+               };
+
+               opp@1700000000_1212 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x10 0x3060>;
+                       opp-hz = /bits/ 64 <1700000000>;
+               };
+
+               opp@1700000000_1237 {
+                       clock-latency-ns = <100000>;
+                       opp-supported-hw = <0x08 0x3060>;
+                       opp-hz = /bits/ 64 <1700000000>;
+               };
+       };
+};
index e074258..55ae050 100644 (file)
                clocks = <&tegra_car TEGRA30_CLK_VDE>;
                reset-names = "vde", "mc";
                resets = <&tegra_car 61>, <&mc TEGRA30_MC_RESET_VDE>;
+               iommus = <&mc TEGRA_SWGROUP_VDE>;
        };
 
        apbmisc@70000800 {
                #reset-cells = <1>;
        };
 
+       memory-controller@7000f400 {
+               compatible = "nvidia,tegra30-emc";
+               reg = <0x7000f400 0x400>;
+               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA30_CLK_EMC>;
+
+               nvidia,memory-controller = <&mc>;
+       };
+
        fuse@7000f800 {
                compatible = "nvidia,tegra30-efuse";
                reg = <0x7000f800 0x400>;
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0>;
+                       clocks = <&tegra_car TEGRA30_CLK_CCLK_G>;
                };
 
                cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <1>;
+                       clocks = <&tegra_car TEGRA30_CLK_CCLK_G>;
                };
 
                cpu@2 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <2>;
+                       clocks = <&tegra_car TEGRA30_CLK_CCLK_G>;
                };
 
                cpu@3 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <3>;
+                       clocks = <&tegra_car TEGRA30_CLK_CCLK_G>;
                };
        };
 
index b6a1eee..fba37b8 100644 (file)
 
 &i2c0 {
        clock-frequency = <400000>;
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c0>;
+       pinctrl-1 = <&pinctrl_i2c0_gpio>;
+       scl-gpios = <&gpio1 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio1 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 };
 
 &nfc {
                        >;
                };
 
+               pinctrl_i2c0_gpio: i2c0gpiogrp {
+                       fsl,pins = <
+                               VF610_PAD_PTB14__GPIO_36                0x37ff
+                               VF610_PAD_PTB15__GPIO_37                0x37ff
+                       >;
+               };
+
                pinctrl_nfc: nfcgrp {
                        fsl,pins = <
                                VF610_PAD_PTD23__NF_IO7         0x28df
index 237b024..92255f8 100644 (file)
@@ -44,7 +44,7 @@
 
 / {
        model = "Toradex Colibri VF50 COM";
-       compatible = "toradex,vf610-colibri_vf50", "fsl,vf500";
+       compatible = "toradex,vf500-colibri_vf50", "fsl,vf500";
 
        memory@80000000 {
                device_type = "memory";
index 0f3870d..830c854 100644 (file)
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart0>;
+       /delete-property/dma-names;
        status = "okay";
 };
 
 &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1>;
+       /delete-property/dma-names;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart2>;
+       /delete-property/dma-names;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart3>;
+       /delete-property/dma-names;
        status = "okay";
 };
 
index c8ebb23..d7caf61 100644 (file)
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
-                                       port@1 {
-                                               reg = <1>;
-                                               label = "internal_j9";
-                                       };
-
                                        port@2 {
                                                reg = <2>;
                                                label = "eth_fc_1000_2";
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
-                                       port@1 {
-                                               reg = <1>;
-                                               label = "internal_j8";
-                                       };
-
                                        port@2 {
                                                reg = <2>;
                                                label = "eth_fc_1000_8";
        linux,rs485-enabled-at-boot-time;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1>;
-       rs485-rts-delay = <0 200>;
        status = "okay";
 };
 
        linux,rs485-enabled-at-boot-time;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart2>;
-       rs485-rts-delay = <0 200>;
        status = "okay";
 };
 
index 1857df9..303f75a 100644 (file)
@@ -132,10 +132,12 @@ CONFIG_ASPEED_BT_IPMI_BMC=y
 CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA9541=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_ASPEED=y
 CONFIG_I2C_FSI=y
+CONFIG_SPI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_ASPEED=y
@@ -185,6 +187,12 @@ CONFIG_USB_CONFIGFS_F_LB_SS=y
 CONFIG_USB_CONFIGFS_F_FS=y
 CONFIG_USB_CONFIGFS_F_HID=y
 CONFIG_USB_CONFIGFS_F_PRINTER=y
+CONFIG_MMC=y
+# CONFIG_PWRSEQ_EMMC is not set
+# CONFIG_PWRSEQ_SIMPLE is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ASPEED=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_CLASS_FLASH=y
@@ -216,7 +224,6 @@ CONFIG_FSI_MASTER_GPIO=y
 CONFIG_FSI_MASTER_HUB=y
 CONFIG_FSI_MASTER_AST_CF=y
 CONFIG_FSI_SCOM=y
-CONFIG_FSI_SBEFIFO=y
 CONFIG_FANOTIFY=y
 CONFIG_OVERLAY_FS=y
 CONFIG_TMPFS=y
@@ -231,7 +238,6 @@ CONFIG_SQUASHFS_ZSTD=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_HARDENED_USERCOPY=y
 CONFIG_FORTIFY_SOURCE=y
-# CONFIG_CRYPTO_ECHAINIV is not set
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_USER_API_HASH=y
@@ -247,14 +253,14 @@ CONFIG_DEBUG_INFO_REDUCED=y
 CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_GDB_SCRIPTS=y
 CONFIG_STRIP_ASM_SYMS=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_PANIC_TIMEOUT=-1
 CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_DETECT_HUNG_TASK is not set
 CONFIG_WQ_WATCHDOG=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_PANIC_TIMEOUT=-1
 # CONFIG_SCHED_DEBUG is not set
-CONFIG_SCHED_STACK_END_CHECK=y
 CONFIG_FUNCTION_TRACER=y
-# CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_DEBUG_WX=y
 CONFIG_DEBUG_USER=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
index 597536c..b0d056d 100644 (file)
@@ -139,6 +139,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=6
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_ASPEED_VUART=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_ASPEED_KCS_IPMI_BMC=y
 CONFIG_ASPEED_BT_IPMI_BMC=y
@@ -154,6 +155,7 @@ CONFIG_SPI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_ASPEED=y
+CONFIG_GPIO_ASPEED_SGPIO=y
 CONFIG_W1=y
 CONFIG_W1_MASTER_GPIO=y
 CONFIG_W1_SLAVE_THERM=y
@@ -236,8 +238,10 @@ CONFIG_FSI=y
 CONFIG_FSI_MASTER_GPIO=y
 CONFIG_FSI_MASTER_HUB=y
 CONFIG_FSI_MASTER_AST_CF=y
+CONFIG_FSI_MASTER_ASPEED=y
 CONFIG_FSI_SCOM=y
 CONFIG_FSI_SBEFIFO=y
+CONFIG_FSI_OCC=y
 CONFIG_FANOTIFY=y
 CONFIG_OVERLAY_FS=y
 CONFIG_TMPFS=y
index 309c55a..3729a6e 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_ARCH_MULTI_V5=y
 CONFIG_ARCH_AT91=y
 CONFIG_SOC_AT91RM9200=y
 CONFIG_SOC_AT91SAM9=y
+# CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
 CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
index 08db1c8..fde84f1 100644 (file)
@@ -230,6 +230,7 @@ CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994=y
 CONFIG_SND_SOC_SMDK_WM8994_PCM=y
 CONFIG_SND_SOC_SNOW=y
 CONFIG_SND_SOC_ODROID=y
+CONFIG_SND_SOC_ARNDALE=y
 CONFIG_SND_SIMPLE_CARD=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -294,6 +295,7 @@ CONFIG_DEVFREQ_GOV_PERFORMANCE=y
 CONFIG_DEVFREQ_GOV_POWERSAVE=y
 CONFIG_DEVFREQ_GOV_USERSPACE=y
 CONFIG_ARM_EXYNOS_BUS_DEVFREQ=y
+CONFIG_EXYNOS5422_DMC=y
 CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=y
 CONFIG_EXTCON=y
 CONFIG_EXTCON_MAX14577=y
@@ -348,6 +350,7 @@ CONFIG_PRINTK_TIME=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_INFO=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_DETECT_HUNG_TASK is not set
index 0f7381e..3608e55 100644 (file)
@@ -179,6 +179,7 @@ CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_TOUCHSCREEN_DA9052=y
 CONFIG_TOUCHSCREEN_EGALAX=y
 CONFIG_TOUCHSCREEN_GOODIX=y
 CONFIG_TOUCHSCREEN_MAX11801=y
@@ -236,6 +237,7 @@ CONFIG_DA9062_WATCHDOG=y
 CONFIG_DA9063_WATCHDOG=m
 CONFIG_RN5T618_WATCHDOG=y
 CONFIG_IMX2_WDT=y
+CONFIG_IMX7ULP_WDT=y
 CONFIG_MFD_DA9052_I2C=y
 CONFIG_MFD_DA9062=y
 CONFIG_MFD_DA9063=y
@@ -335,7 +337,7 @@ CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_MXS_PHY=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_FSL_USB2=y
-CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS=y
 CONFIG_USB_CONFIGFS_SERIAL=y
 CONFIG_USB_CONFIGFS_ACM=y
 CONFIG_USB_CONFIGFS_OBEX=y
@@ -460,6 +462,7 @@ CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_PROVE_LOCKING=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
index f33f5d7..11e2211 100644 (file)
@@ -134,6 +134,7 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
 CONFIG_TI_KEYSTONE_NETCP=y
 CONFIG_TI_KEYSTONE_NETCP_ETHSS=y
+CONFIG_TI_CPTS=y
 CONFIG_MARVELL_PHY=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
index 0b42bdd..e530107 100644 (file)
@@ -4,22 +4,19 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EMBEDDED=y
 CONFIG_SLOB=y
-CONFIG_JUMP_LABEL=y
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_MULTI_V4T=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_AT91=y
 CONFIG_SOC_AT91RM9200=y
 CONFIG_ARCH_CLPS711X=y
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX1=y
 CONFIG_ARCH_INTEGRATOR=y
 CONFIG_ARCH_INTEGRATOR_AP=y
 CONFIG_INTEGRATOR_IMPD1=y
 CONFIG_INTEGRATOR_CM720T=y
 CONFIG_INTEGRATOR_CM920T=y
 CONFIG_INTEGRATOR_CM922T_XA10=y
-CONFIG_ARCH_MXC=y
-CONFIG_SOC_IMX1=y
 CONFIG_ARCH_NSPIRE=y
 CONFIG_AEABI=y
 # CONFIG_ATAGS is not set
@@ -28,6 +25,8 @@ CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_ARM_CLPS711X_CPUIDLE=y
+CONFIG_JUMP_LABEL=y
+CONFIG_PARTITION_ADVANCED=y
 # CONFIG_COREDUMP is not set
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -81,7 +80,6 @@ CONFIG_FB=y
 CONFIG_FB_CLPS711X=y
 CONFIG_FB_IMX=y
 CONFIG_LCD_PLATFORM=y
-CONFIG_BACKLIGHT_PWM=y
 # CONFIG_USB_SUPPORT is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
@@ -92,12 +90,11 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_PWM=y
 CONFIG_PWM_ATMEL=y
 CONFIG_PWM_CLPS711X=y
-CONFIG_PWM_IMX=y
 CONFIG_EXT2_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_CRAMFS=y
 CONFIG_MINIX_FS=y
+CONFIG_CRC_CCITT=y
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
-CONFIG_CRC_CCITT=y
index bd01887..2724fb3 100644 (file)
@@ -1,14 +1,11 @@
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_LOG_BUF_SHIFT=19
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
@@ -59,8 +56,6 @@ CONFIG_MACH_RD88F5181L_GE=y
 CONFIG_MACH_RD88F5181L_FXO=y
 CONFIG_MACH_RD88F6183AP_GE=y
 CONFIG_ARCH_U300=y
-CONFIG_PCI_MVEBU=y
-CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -72,6 +67,10 @@ CONFIG_CPU_FREQ_STAT=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_KIRKWOOD_CPUIDLE=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -84,6 +83,7 @@ CONFIG_NET_DSA=y
 CONFIG_NET_PKTGEN=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
+CONFIG_PCI_MVEBU=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_IMX_WEIM=y
@@ -165,6 +165,7 @@ CONFIG_SPI_ATMEL=y
 CONFIG_SPI_IMX=y
 CONFIG_SPI_ORION=y
 CONFIG_GPIO_ASPEED=m
+CONFIG_GPIO_ASPEED_SGPIO=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_POWER_RESET_QNAP=y
@@ -186,7 +187,6 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_SOC_CAMERA=y
 CONFIG_VIDEO_ASPEED=m
 CONFIG_VIDEO_ATMEL_ISI=m
 CONFIG_DRM=y
@@ -241,6 +241,9 @@ CONFIG_USB_ASPEED_VHUB=m
 CONFIG_USB_CONFIGFS=m
 CONFIG_MMC=y
 CONFIG_SDIO_UART=y
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_SDHCI_PLTFM=m
+CONFIG_MMC_SDHCI_OF_ASPEED=m
 CONFIG_MMC_ATMELMCI=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_NEW_LEDS=y
@@ -263,7 +266,6 @@ CONFIG_DMADEVICES=y
 CONFIG_AT_HDMAC=y
 CONFIG_MV_XOR=y
 CONFIG_STAGING=y
-CONFIG_FB_XGI=y
 CONFIG_ASPEED_LPC_CTRL=m
 CONFIG_ASPEED_LPC_SNOOP=m
 CONFIG_ASPEED_P2A_CTRL=m
@@ -292,6 +294,11 @@ CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_2=y
 CONFIG_NLS_UTF8=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_DEV_MARVELL_CESA=y
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
@@ -300,8 +307,3 @@ CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_DEV_MARVELL_CESA=y
-CONFIG_CRC_CCITT=y
-CONFIG_LIBCRC32C=y
index e4c8def..3f1b96d 100644 (file)
@@ -53,6 +53,9 @@ CONFIG_ARCH_MEDIATEK=y
 CONFIG_ARCH_MESON=y
 CONFIG_ARCH_MILBEAUT=y
 CONFIG_ARCH_MILBEAUT_M10V=y
+CONFIG_ARCH_MMP=y
+CONFIG_MACH_MMP2_DT=y
+CONFIG_MACH_MMP3_DT=y
 CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_ARMADA_370=y
 CONFIG_MACH_ARMADA_375=y
@@ -128,8 +131,6 @@ CONFIG_CRYPTO_AES_ARM_CE=m
 CONFIG_CRYPTO_GHASH_ARM_CE=m
 CONFIG_CRYPTO_CRC32_ARM_CE=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
-CONFIG_GCC_PLUGINS=y
-CONFIG_GCC_PLUGIN_STRUCTLEAK=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
@@ -168,13 +169,20 @@ CONFIG_MAC80211=m
 CONFIG_RFKILL=y
 CONFIG_RFKILL_INPUT=y
 CONFIG_RFKILL_GPIO=y
+CONFIG_NFC=m
+CONFIG_NFC_DIGITAL=m
+CONFIG_NFC_NCI=m
+CONFIG_NFC_NCI_SPI=m
+CONFIG_NFC_NCI_UART=m
+CONFIG_NFC_HCI=m
+CONFIG_NFC_SHDLC=y
+CONFIG_NFC_S3FWRN5_I2C=m
 CONFIG_PCIEPORTBUS=y
 CONFIG_PCI_MVEBU=y
 CONFIG_PCI_TEGRA=y
 CONFIG_PCI_RCAR_GEN2=y
 CONFIG_PCIE_RCAR=y
 CONFIG_PCI_DRA7XX_EP=y
-CONFIG_PCI_KEYSTONE=y
 CONFIG_PCI_ENDPOINT=y
 CONFIG_PCI_ENDPOINT_CONFIGFS=y
 CONFIG_PCI_EPF_TEST=m
@@ -189,15 +197,14 @@ CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_NAND_OMAP2=y
 CONFIG_MTD_NAND_OMAP_BCH=y
 CONFIG_MTD_NAND_ATMEL=y
 CONFIG_MTD_NAND_MARVELL=y
-CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_BRCMNAND=y
+CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_VF610_NFC=y
 CONFIG_MTD_NAND_DAVINCI=y
 CONFIG_MTD_NAND_STM32_FMC2=y
@@ -244,6 +251,7 @@ CONFIG_BGMAC_BCMA=y
 CONFIG_SYSTEMPORT=m
 CONFIG_MACB=y
 CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_FTGMAC100=m
 CONFIG_GIANFAR=y
 CONFIG_HIX5HD2_GMAC=y
 CONFIG_E1000E=y
@@ -260,11 +268,11 @@ CONFIG_STMMAC_ETH=y
 CONFIG_DWMAC_DWC_QOS_ETH=y
 CONFIG_TI_CPSW=y
 CONFIG_XILINX_EMACLITE=y
-CONFIG_AT803X_PHY=y
 CONFIG_BROADCOM_PHY=y
 CONFIG_ICPLUS_PHY=y
 CONFIG_MARVELL_PHY=y
 CONFIG_MICREL_PHY=y
+CONFIG_AT803X_PHY=y
 CONFIG_ROCKCHIP_PHY=y
 CONFIG_SMSC_PHY=y
 CONFIG_USB_PEGASUS=y
@@ -283,6 +291,7 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_QT1070=m
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_TEGRA=y
+CONFIG_KEYBOARD_PXA27x=m
 CONFIG_KEYBOARD_SAMSUNG=m
 CONFIG_KEYBOARD_ST_KEYSCAN=y
 CONFIG_KEYBOARD_SPEAR=y
@@ -377,7 +386,6 @@ CONFIG_I2C_DAVINCI=y
 CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_I2C_DIGICOLOR=m
 CONFIG_I2C_EMEV2=m
-CONFIG_I2C_GPIO=m
 CONFIG_I2C_IMX=y
 CONFIG_I2C_MESON=y
 CONFIG_I2C_MV64XXX=y
@@ -437,6 +445,7 @@ CONFIG_PINCTRL_MSM8X74=y
 CONFIG_PINCTRL_MSM8916=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
+CONFIG_GPIO_ASPEED_SGPIO=y
 CONFIG_GPIO_DAVINCI=y
 CONFIG_GPIO_DWAPB=y
 CONFIG_GPIO_EM=y
@@ -467,8 +476,8 @@ CONFIG_BATTERY_BQ27XXX=m
 CONFIG_AXP20X_POWER=m
 CONFIG_BATTERY_MAX17040=m
 CONFIG_BATTERY_MAX17042=m
-CONFIG_CHARGER_GPIO=m
 CONFIG_CHARGER_CPCAP=m
+CONFIG_CHARGER_GPIO=m
 CONFIG_CHARGER_MAX14577=m
 CONFIG_CHARGER_MAX77693=m
 CONFIG_CHARGER_MAX8997=m
@@ -491,12 +500,12 @@ CONFIG_BCM2835_THERMAL=m
 CONFIG_BRCMSTB_THERMAL=m
 CONFIG_ST_THERMAL_MEMMAP=y
 CONFIG_UNIPHIER_THERMAL=y
-CONFIG_WATCHDOG=y
 CONFIG_DA9063_WATCHDOG=m
 CONFIG_XILINX_WATCHDOG=y
 CONFIG_ARM_SP805_WATCHDOG=y
 CONFIG_AT91SAM9X_WATCHDOG=y
 CONFIG_SAMA5D4_WATCHDOG=y
+CONFIG_S3C2410_WATCHDOG=m
 CONFIG_DW_WATCHDOG=y
 CONFIG_DAVINCI_WATCHDOG=m
 CONFIG_ORION_WATCHDOG=y
@@ -525,10 +534,6 @@ CONFIG_MFD_BCM590XX=y
 CONFIG_MFD_AC100=y
 CONFIG_MFD_AXP20X_I2C=y
 CONFIG_MFD_AXP20X_RSB=y
-CONFIG_MFD_CROS_EC=m
-CONFIG_CROS_EC_I2C=m
-CONFIG_CROS_EC_SPI=m
-CONFIG_MFD_CROS_EC_CHARDEV=m
 CONFIG_MFD_DA9063=m
 CONFIG_MFD_MAX14577=y
 CONFIG_MFD_MAX77686=y
@@ -581,6 +586,7 @@ CONFIG_REGULATOR_QCOM_RPM=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=m
 CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_RN5T618=y
+CONFIG_REGULATOR_S2MPA01=m
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_STM32_BOOSTER=m
@@ -605,6 +611,7 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MMP_CAMERA=m
 CONFIG_VIDEO_ASPEED=m
 CONFIG_VIDEO_STM32_DCMI=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
@@ -628,7 +635,6 @@ CONFIG_V4L_TEST_DRIVERS=y
 CONFIG_VIDEO_VIVID=m
 CONFIG_CEC_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_SAMSUNG_S5P_CEC=m
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_ML86V7667=m
 CONFIG_DRM=y
@@ -681,7 +687,6 @@ CONFIG_FB_EFI=y
 CONFIG_FB_WM8505=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 CONFIG_FB_SIMPLE=y
-CONFIG_LCD_PLATFORM=m
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
 CONFIG_BACKLIGHT_GPIO=y
@@ -702,6 +707,9 @@ CONFIG_SND_ATMEL_SOC_PDMIC=m
 CONFIG_SND_ATMEL_SOC_I2S=m
 CONFIG_SND_BCM2835_SOC_I2S=m
 CONFIG_SND_SOC_FSL_SAI=m
+CONFIG_SND_MMP_SOC=y
+CONFIG_SND_PXA_SOC_SSP=m
+CONFIG_SND_PXA910_SOC=m
 CONFIG_SND_SOC_ROCKCHIP=m
 CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
 CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
@@ -711,9 +719,12 @@ CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994=m
 CONFIG_SND_SOC_SMDK_WM8994_PCM=m
 CONFIG_SND_SOC_SNOW=m
 CONFIG_SND_SOC_ODROID=m
+CONFIG_SND_SOC_ARNDALE=m
 CONFIG_SND_SOC_SH4_FSI=m
 CONFIG_SND_SOC_RCAR=m
 CONFIG_SND_SOC_STI=m
+CONFIG_SND_SOC_STM32_SAI=m
+CONFIG_SND_SOC_STM32_I2S=m
 CONFIG_SND_SUN4I_CODEC=m
 CONFIG_SND_SOC_TEGRA=m
 CONFIG_SND_SOC_TEGRA20_I2S=m
@@ -727,10 +738,12 @@ CONFIG_SND_SOC_TEGRA_ALC5632=m
 CONFIG_SND_SOC_TEGRA_MAX98090=m
 CONFIG_SND_SOC_AK4642=m
 CONFIG_SND_SOC_CPCAP=m
+CONFIG_SND_SOC_CS42L51_I2C=m
 CONFIG_SND_SOC_SGTL5000=m
 CONFIG_SND_SOC_SPDIF=m
 CONFIG_SND_SOC_STI_SAS=m
 CONFIG_SND_SOC_WM8978=m
+CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
@@ -740,6 +753,7 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_STI=y
 CONFIG_USB_EHCI_TEGRA=y
 CONFIG_USB_EHCI_EXYNOS=y
+CONFIG_USB_EHCI_MV=m
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_STI=y
 CONFIG_USB_OHCI_EXYNOS=m
@@ -810,6 +824,7 @@ CONFIG_MMC_SDHCI_DOVE=y
 CONFIG_MMC_SDHCI_TEGRA=y
 CONFIG_MMC_SDHCI_S3C=y
 CONFIG_MMC_SDHCI_PXAV3=y
+CONFIG_MMC_SDHCI_PXAV2=m
 CONFIG_MMC_SDHCI_SPEAR=y
 CONFIG_MMC_SDHCI_S3C_DMA=y
 CONFIG_MMC_SDHCI_BCM_KONA=y
@@ -875,6 +890,7 @@ CONFIG_RTC_DRV_DA9063=m
 CONFIG_RTC_DRV_EFI=m
 CONFIG_RTC_DRV_DIGICOLOR=m
 CONFIG_RTC_DRV_S3C=m
+CONFIG_RTC_DRV_SA1100=m
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_AT91RM9200=m
 CONFIG_RTC_DRV_AT91SAM9=m
@@ -919,6 +935,9 @@ CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
 CONFIG_STAGING_BOARD=y
+CONFIG_MFD_CROS_EC=m
+CONFIG_CROS_EC_I2C=m
+CONFIG_CROS_EC_SPI=m
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_COMMON_CLK_RK808=m
 CONFIG_COMMON_CLK_S2MPS11=m
@@ -933,6 +952,7 @@ CONFIG_BCM2835_MBOX=y
 CONFIG_ROCKCHIP_IOMMU=y
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
+CONFIG_EXYNOS_IOMMU=y
 CONFIG_REMOTEPROC=y
 CONFIG_ST_REMOTEPROC=m
 CONFIG_RPMSG_VIRTIO=m
@@ -967,8 +987,14 @@ CONFIG_ARCH_TEGRA_2x_SOC=y
 CONFIG_ARCH_TEGRA_3x_SOC=y
 CONFIG_ARCH_TEGRA_114_SOC=y
 CONFIG_ARCH_TEGRA_124_SOC=y
+CONFIG_ARM_EXYNOS_BUS_DEVFREQ=m
 CONFIG_ARM_TEGRA_DEVFREQ=m
+CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=m
+CONFIG_EXTCON_MAX14577=m
+CONFIG_EXTCON_MAX77693=m
+CONFIG_EXTCON_MAX8997=m
 CONFIG_TI_AEMIF=y
+CONFIG_EXYNOS5422_DMC=m
 CONFIG_IIO=y
 CONFIG_IIO_SW_TRIGGER=y
 CONFIG_ASPEED_ADC=m
@@ -978,16 +1004,15 @@ CONFIG_BERLIN2_ADC=m
 CONFIG_CPCAP_ADC=m
 CONFIG_EXYNOS_ADC=m
 CONFIG_MESON_SARADC=m
+CONFIG_ROCKCHIP_SARADC=m
 CONFIG_STM32_ADC_CORE=m
 CONFIG_STM32_ADC=m
 CONFIG_STM32_DFSDM_ADC=m
 CONFIG_VF610_ADC=m
 CONFIG_XILINX_XADC=y
-CONFIG_STM32_LPTIMER_CNT=m
-CONFIG_STM32_DAC=m
-CONFIG_ROCKCHIP_SARADC=m
 CONFIG_IIO_CROS_EC_SENSORS_CORE=m
 CONFIG_IIO_CROS_EC_SENSORS=m
+CONFIG_STM32_DAC=m
 CONFIG_MPU3050_I2C=y
 CONFIG_CM36651=m
 CONFIG_IIO_CROS_EC_LIGHT_PROX=m
@@ -1020,12 +1045,14 @@ CONFIG_PHY_SUN9I_USB=y
 CONFIG_PHY_HIX5HD2_SATA=y
 CONFIG_PHY_BERLIN_SATA=y
 CONFIG_PHY_BERLIN_USB=y
+CONFIG_PHY_MMP3_USB=m
 CONFIG_PHY_CPCAP_USB=m
 CONFIG_PHY_QCOM_APQ8064_SATA=m
 CONFIG_PHY_RCAR_GEN2=m
 CONFIG_PHY_ROCKCHIP_DP=m
 CONFIG_PHY_ROCKCHIP_USB=y
 CONFIG_PHY_SAMSUNG_USB2=m
+CONFIG_PHY_EXYNOS5250_SATA=m
 CONFIG_PHY_UNIPHIER_USB2=y
 CONFIG_PHY_UNIPHIER_USB3=y
 CONFIG_PHY_MIPHY28LP=y
@@ -1036,11 +1063,18 @@ CONFIG_PHY_DM816X_USB=m
 CONFIG_OMAP_USB2=y
 CONFIG_TI_PIPE3=y
 CONFIG_TWL4030_USB=m
-CONFIG_MESON_MX_EFUSE=m
-CONFIG_ROCKCHIP_EFUSE=m
 CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_ROCKCHIP_EFUSE=m
 CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_NVMEM_VF610_OCOTP=y
+CONFIG_MESON_MX_EFUSE=m
+CONFIG_FSI=m
+CONFIG_FSI_MASTER_GPIO=m
+CONFIG_FSI_MASTER_HUB=m
+CONFIG_FSI_MASTER_ASPEED=m
+CONFIG_FSI_SCOM=m
+CONFIG_FSI_SBEFIFO=m
+CONFIG_FSI_OCC=m
 CONFIG_EXT4_FS=y
 CONFIG_AUTOFS4_FS=y
 CONFIG_MSDOS_FS=y
@@ -1067,14 +1101,15 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
+CONFIG_CRYPTO_DEV_SUN4I_SS=m
 CONFIG_CRYPTO_DEV_MARVELL_CESA=m
 CONFIG_CRYPTO_DEV_EXYNOS_RNG=m
 CONFIG_CRYPTO_DEV_S5P=m
 CONFIG_CRYPTO_DEV_ATMEL_AES=m
 CONFIG_CRYPTO_DEV_ATMEL_TDES=m
 CONFIG_CRYPTO_DEV_ATMEL_SHA=m
-CONFIG_CRYPTO_DEV_SUN4I_SS=m
 CONFIG_CRYPTO_DEV_ROCKCHIP=m
 CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
index 89cce8d..c32c338 100644 (file)
@@ -92,6 +92,7 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NETFILTER=y
 CONFIG_PHONET=m
+CONFIG_NET_SWITCHDEV=y
 CONFIG_CAN=m
 CONFIG_CAN_C_CAN=m
 CONFIG_CAN_C_CAN_PLATFORM=m
@@ -128,7 +129,6 @@ CONFIG_PCI_ENDPOINT_CONFIGFS=y
 CONFIG_PCI_EPF_TEST=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_DMA_CMA=y
 CONFIG_OMAP_OCP2SCP=y
 CONFIG_CONNECTOR=m
 CONFIG_MTD=y
@@ -182,6 +182,7 @@ CONFIG_SMSC911X=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 CONFIG_TI_DAVINCI_EMAC=y
 CONFIG_TI_CPSW=y
+CONFIG_TI_CPSW_SWITCHDEV=y
 CONFIG_TI_CPTS=y
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
@@ -343,18 +344,16 @@ CONFIG_VIDEO_OMAP3=m
 CONFIG_CEC_PLATFORM_DRIVERS=y
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_MT9P031=m
 CONFIG_DRM=m
 CONFIG_DRM_OMAP=m
 CONFIG_OMAP5_DSS_HDMI=y
 CONFIG_OMAP2_DSS_SDI=y
 CONFIG_OMAP2_DSS_DSI=y
 CONFIG_DRM_OMAP_ENCODER_OPA362=m
-CONFIG_DRM_OMAP_ENCODER_TFP410=m
 CONFIG_DRM_OMAP_ENCODER_TPD12S015=m
-CONFIG_DRM_OMAP_CONNECTOR_DVI=m
 CONFIG_DRM_OMAP_CONNECTOR_HDMI=m
 CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV=m
-CONFIG_DRM_OMAP_PANEL_DPI=m
 CONFIG_DRM_OMAP_PANEL_DSI_CM=m
 CONFIG_DRM_TILCDC=m
 CONFIG_DRM_PANEL_SIMPLE=m
@@ -539,11 +538,16 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_SECURITY=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEV_OMAP=m
+CONFIG_CRYPTO_DEV_OMAP_SHAM=m
+CONFIG_CRYPTO_DEV_OMAP_AES=m
+CONFIG_CRYPTO_DEV_OMAP_DES=m
 CONFIG_CRC_CCITT=y
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=y
 CONFIG_CRC7=y
 CONFIG_LIBCRC32C=y
+CONFIG_DMA_CMA=y
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -552,6 +556,6 @@ CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_INFO_SPLIT=y
 CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
 CONFIG_SCHEDSTATS=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_TI_CPSW_SWITCHDEV=y
index 67c306f..4dd1d8c 100644 (file)
@@ -225,6 +225,7 @@ CONFIG_QCOM_WCNSS_PIL=y
 CONFIG_RPMSG_CHAR=y
 CONFIG_RPMSG_QCOM_SMD=y
 CONFIG_QCOM_GSBI=y
+CONFIG_QCOM_OCMEM=y
 CONFIG_QCOM_PM=y
 CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD_RPM=y
index ef78534..27f6135 100644 (file)
@@ -20,6 +20,7 @@ CONFIG_ARCH_AT91=y
 CONFIG_SOC_SAMA5D2=y
 CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
+# CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
 CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
index c6c7035..de38304 100644 (file)
@@ -9,7 +9,6 @@ CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 CONFIG_ARCH_RENESAS=y
 CONFIG_PL310_ERRATA_588369=y
-CONFIG_ARM_ERRATA_754322=y
 CONFIG_SMP=y
 CONFIG_SCHED_MC=y
 CONFIG_NR_CPUS=8
@@ -50,7 +49,6 @@ CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_EEPROM_AT24=y
 CONFIG_BLK_DEV_SD=y
@@ -130,7 +128,6 @@ CONFIG_DRM_SII902X=y
 CONFIG_DRM_I2C_ADV7511=y
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_FB_SH_MOBILE_LCDC=y
-# CONFIG_LCD_CLASS_DEVICE is not set
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
@@ -215,4 +212,5 @@ CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_PRINTK_TIME=y
 # CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
index df433ab..3f5d727 100644 (file)
@@ -56,6 +56,7 @@ CONFIG_SUN4I_EMAC=y
 CONFIG_STMMAC_ETH=y
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MICREL_PHY=y
 # CONFIG_WLAN is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_SUN4I_LRADC=y
@@ -150,4 +151,6 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_FS=y
+CONFIG_CRYPTO_DEV_ALLWINNER=y
+CONFIG_CRYPTO_DEV_SUN8I_CE=y
 CONFIG_CRYPTO_DEV_SUN4I_SS=y
index 8f5c6a5..a27592d 100644 (file)
@@ -250,6 +250,8 @@ CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
+CONFIG_STAGING_MEDIA=y
+CONFIG_TEGRA_VDE=y
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_ARCH_TEGRA_2x_SOC=y
index f3f42cf..776ae07 100644 (file)
@@ -38,6 +38,13 @@ void curve25519_arch(u8 out[CURVE25519_KEY_SIZE],
 }
 EXPORT_SYMBOL(curve25519_arch);
 
+void curve25519_base_arch(u8 pub[CURVE25519_KEY_SIZE],
+                         const u8 secret[CURVE25519_KEY_SIZE])
+{
+       return curve25519_arch(pub, secret, curve25519_base_point);
+}
+EXPORT_SYMBOL(curve25519_base_arch);
+
 static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
                                 unsigned int len)
 {
index 32edfad..a6d4ee8 100644 (file)
 #define L310_AUX_CTRL_STORE_LIMITATION         BIT(11) /* R2P0+ */
 #define L310_AUX_CTRL_EXCLUSIVE_CACHE          BIT(12)
 #define L310_AUX_CTRL_ASSOCIATIVITY_16         BIT(16)
+#define L310_AUX_CTRL_FWA_SHIFT                        23
+#define L310_AUX_CTRL_FWA_MASK                 (3 << 23)
 #define L310_AUX_CTRL_CACHE_REPLACE_RR         BIT(25) /* R2P0+ */
 #define L310_AUX_CTRL_NS_LOCKDOWN              BIT(26)
 #define L310_AUX_CTRL_NS_INT_CTRL              BIT(27)
index 3ae120c..eabcb48 100644 (file)
@@ -12,7 +12,7 @@
 
 #ifndef CONFIG_MMU
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 #include <asm/pgtable-nommu.h>
 
 #else
index 5b879ae..0ad2429 100644 (file)
@@ -75,6 +75,9 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode)
 #ifdef CONFIG_ARM_ARCH_TIMER
        u64 cycle_now;
 
+       if (!clock_mode)
+               return -EINVAL;
+
        isb();
        cycle_now = read_sysreg(CNTVCT);
 
index 4b0bab2..46e1be9 100644 (file)
@@ -240,6 +240,10 @@ int __cpu_disable(void)
        if (ret)
                return ret;
 
+#ifdef CONFIG_GENERIC_ARCH_TOPOLOGY
+       remove_cpu_topology(cpu);
+#endif
+
        /*
         * Take this CPU offline.  Once we clear this, we can't return,
         * and we must not schedule until we're ready to give up the cpu.
index 3a4dde0..b5adaf7 100644 (file)
@@ -196,9 +196,8 @@ void store_cpu_topology(unsigned int cpuid)
        struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
        unsigned int mpidr;
 
-       /* If the cpu topology has been already set, just return */
-       if (cpuid_topo->core_id != -1)
-               return;
+       if (cpuid_topo->package_id != -1)
+               goto topology_populated;
 
        mpidr = read_cpuid_mpidr();
 
@@ -231,14 +230,15 @@ void store_cpu_topology(unsigned int cpuid)
                cpuid_topo->package_id = -1;
        }
 
-       update_siblings_masks(cpuid);
-
        update_cpu_capacity(cpuid);
 
        pr_info("CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
                cpuid, cpu_topology[cpuid].thread_id,
                cpu_topology[cpuid].core_id,
                cpu_topology[cpuid].package_id, mpidr);
+
+topology_populated:
+       update_siblings_masks(cpuid);
 }
 
 static inline int cpu_corepower_flags(void)
index 5e5f1fa..e4e25f2 100644 (file)
@@ -161,6 +161,8 @@ config ARCH_BCM2835
        select GPIOLIB
        select ARM_AMBA
        select ARM_ERRATA_411920 if ARCH_MULTI_V6
+       select ARM_GIC if ARCH_MULTI_V7
+       select ZONE_DMA if ARCH_MULTI_V7
        select ARM_TIMER_SP804
        select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
        select TIMER_OF
@@ -169,7 +171,7 @@ config ARCH_BCM2835
        select PINCTRL_BCM2835
        select MFD_CORE
        help
-         This enables support for the Broadcom BCM2835 and BCM2836 SoCs.
+         This enables support for the Broadcom BCM2711 and BCM283x SoCs.
          This SoC is used in the Raspberry Pi and Roku 2 devices.
 
 config ARCH_BCM_53573
index b59c813..7baa8c9 100644 (file)
@@ -42,8 +42,9 @@ obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
 obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o
 
 # BCM2835
-obj-$(CONFIG_ARCH_BCM2835)     += board_bcm2835.o
 ifeq ($(CONFIG_ARCH_BCM2835),y)
+obj-y                          += board_bcm2835.o
+obj-y                          += bcm2711.o
 ifeq ($(CONFIG_ARM),y)
 obj-$(CONFIG_SMP)              += platsmp.o
 endif
diff --git a/arch/arm/mach-bcm/bcm2711.c b/arch/arm/mach-bcm/bcm2711.c
new file mode 100644 (file)
index 0000000..fa0300d
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Stefan Wahren
+ */
+
+#include <linux/of_address.h>
+
+#include <asm/mach/arch.h>
+
+#include "platsmp.h"
+
+static const char * const bcm2711_compat[] = {
+#ifdef CONFIG_ARCH_MULTI_V7
+       "brcm,bcm2711",
+#endif
+       NULL
+};
+
+DT_MACHINE_START(BCM2711, "BCM2711")
+#ifdef CONFIG_ZONE_DMA
+       .dma_zone_size  = SZ_1G,
+#endif
+       .dt_compat = bcm2711_compat,
+       .smp = smp_ops(bcm2836_smp_ops),
+MACHINE_END
index 541e850..43a16f9 100644 (file)
@@ -140,7 +140,7 @@ static int bcm_kona_do_smc(u32 service_id, u32 buffer_phys)
 static void __bcm_kona_smc(void *info)
 {
        struct bcm_kona_smc_data *data = info;
-       u32 *args = bcm_smc_buffer;
+       u32 __iomem *args = bcm_smc_buffer;
 
        BUG_ON(smp_processor_id() != 0);
        BUG_ON(!args);
index 47f8053..21400b3 100644 (file)
@@ -22,6 +22,8 @@
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 
+#include "platsmp.h"
+
 /* Size of mapped Cortex A9 SCU address space */
 #define CORTEX_A9_SCU_SIZE     0x58
 
index 9dab1f5..4ef5657 100644 (file)
@@ -13,6 +13,7 @@ menuconfig ARCH_EXYNOS
        select ARM_AMBA
        select ARM_GIC
        select COMMON_CLK_SAMSUNG
+       select EXYNOS_ASV
        select EXYNOS_CHIPID
        select EXYNOS_THERMAL
        select EXYNOS_PMU
index 98338a4..3b010fe 100644 (file)
@@ -15,7 +15,6 @@ menu "Hisilicon platform type"
 
 config ARCH_HI3xxx
        bool "Hisilicon Hi36xx family"
-       depends on ARCH_MULTI_V7
        select CACHE_L2X0
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
@@ -25,17 +24,15 @@ config ARCH_HI3xxx
          Support for Hisilicon Hi36xx SoC family
 
 config ARCH_HIP01
-       bool "Hisilicon HIP01 family"
-       depends on ARCH_MULTI_V7
-       select HAVE_ARM_SCU if SMP
-       select HAVE_ARM_TWD if SMP
-       select ARM_GLOBAL_TIMER
-       help
-         Support for Hisilicon HIP01 SoC family
+       bool "Hisilicon HIP01 family"
+       select HAVE_ARM_SCU if SMP
+       select HAVE_ARM_TWD if SMP
+       select ARM_GLOBAL_TIMER
+       help
+         Support for Hisilicon HIP01 SoC family
 
 config ARCH_HIP04
        bool "Hisilicon HiP04 Cortex A15 family"
-       depends on ARCH_MULTI_V7
        select ARM_ERRATA_798181 if SMP
        select HAVE_ARM_ARCH_TIMER
        select MCPM if SMP
@@ -46,7 +43,6 @@ config ARCH_HIP04
 
 config ARCH_HIX5HD2
        bool "Hisilicon X5HD2 family"
-       depends on ARCH_MULTI_V7
        select CACHE_L2X0
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
index 777d8c2..8fb68c0 100644 (file)
@@ -19,8 +19,6 @@
 #define ANADIG_REG_2P5         0x130
 #define ANADIG_REG_CORE                0x140
 #define ANADIG_ANA_MISC0       0x150
-#define ANADIG_USB1_CHRG_DETECT        0x1b0
-#define ANADIG_USB2_CHRG_DETECT        0x210
 #define ANADIG_DIGPROG         0x260
 #define ANADIG_DIGPROG_IMX6SL  0x280
 #define ANADIG_DIGPROG_IMX7D   0x800
@@ -33,8 +31,6 @@
 #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG   0x1000
 /* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */
 #define BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS   0x2000
-#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B   0x80000
-#define BM_ANADIG_USB_CHRG_DETECT_EN_B         0x100000
 
 static struct regmap *anatop;
 
@@ -96,16 +92,6 @@ void imx_anatop_post_resume(void)
 
 }
 
-static void imx_anatop_usb_chrg_detect_disable(void)
-{
-       regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
-               BM_ANADIG_USB_CHRG_DETECT_EN_B
-               | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
-       regmap_write(anatop, ANADIG_USB2_CHRG_DETECT,
-               BM_ANADIG_USB_CHRG_DETECT_EN_B |
-               BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
-}
-
 void __init imx_init_revision_from_anatop(void)
 {
        struct device_node *np;
@@ -171,10 +157,6 @@ void __init imx_init_revision_from_anatop(void)
 void __init imx_anatop_init(void)
 {
        anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
-       if (IS_ERR(anatop)) {
+       if (IS_ERR(anatop))
                pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
-               return;
-       }
-
-       imx_anatop_usb_chrg_detect_disable();
 }
index 0b137ee..871f983 100644 (file)
@@ -1,15 +1,20 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/err.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
 
 #include "hardware.h"
 #include "common.h"
 
+#define OCOTP_UID_H    0x420
+#define OCOTP_UID_L    0x410
+
 unsigned int __mxc_cpu_type;
 static unsigned int imx_soc_revision;
 
@@ -76,9 +81,13 @@ void __init imx_aips_allow_unprivileged_access(
 struct device * __init imx_soc_device_init(void)
 {
        struct soc_device_attribute *soc_dev_attr;
+       const char *ocotp_compat = NULL;
        struct soc_device *soc_dev;
        struct device_node *root;
+       struct regmap *ocotp = NULL;
        const char *soc_id;
+       u64 soc_uid = 0;
+       u32 val;
        int ret;
 
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
@@ -119,30 +128,39 @@ struct device * __init imx_soc_device_init(void)
                soc_id = "i.MX53";
                break;
        case MXC_CPU_IMX6SL:
+               ocotp_compat = "fsl,imx6sl-ocotp";
                soc_id = "i.MX6SL";
                break;
        case MXC_CPU_IMX6DL:
+               ocotp_compat = "fsl,imx6q-ocotp";
                soc_id = "i.MX6DL";
                break;
        case MXC_CPU_IMX6SX:
+               ocotp_compat = "fsl,imx6sx-ocotp";
                soc_id = "i.MX6SX";
                break;
        case MXC_CPU_IMX6Q:
+               ocotp_compat = "fsl,imx6q-ocotp";
                soc_id = "i.MX6Q";
                break;
        case MXC_CPU_IMX6UL:
+               ocotp_compat = "fsl,imx6ul-ocotp";
                soc_id = "i.MX6UL";
                break;
        case MXC_CPU_IMX6ULL:
+               ocotp_compat = "fsl,imx6ull-ocotp";
                soc_id = "i.MX6ULL";
                break;
        case MXC_CPU_IMX6ULZ:
+               ocotp_compat = "fsl,imx6ull-ocotp";
                soc_id = "i.MX6ULZ";
                break;
        case MXC_CPU_IMX6SLL:
+               ocotp_compat = "fsl,imx6sll-ocotp";
                soc_id = "i.MX6SLL";
                break;
        case MXC_CPU_IMX7D:
+               ocotp_compat = "fsl,imx7d-ocotp";
                soc_id = "i.MX7D";
                break;
        case MXC_CPU_IMX7ULP:
@@ -153,18 +171,38 @@ struct device * __init imx_soc_device_init(void)
        }
        soc_dev_attr->soc_id = soc_id;
 
+       if (ocotp_compat) {
+               ocotp = syscon_regmap_lookup_by_compatible(ocotp_compat);
+               if (IS_ERR(ocotp))
+                       pr_err("%s: failed to find %s regmap!\n", __func__, ocotp_compat);
+       }
+
+       if (!IS_ERR_OR_NULL(ocotp)) {
+               regmap_read(ocotp, OCOTP_UID_H, &val);
+               soc_uid = val;
+               regmap_read(ocotp, OCOTP_UID_L, &val);
+               soc_uid <<= 32;
+               soc_uid |= val;
+       }
+
        soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
                                           (imx_soc_revision >> 4) & 0xf,
                                           imx_soc_revision & 0xf);
        if (!soc_dev_attr->revision)
                goto free_soc;
 
+       soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", soc_uid);
+       if (!soc_dev_attr->serial_number)
+               goto free_rev;
+
        soc_dev = soc_device_register(soc_dev_attr);
        if (IS_ERR(soc_dev))
-               goto free_rev;
+               goto free_serial_number;
 
        return soc_device_to_device(soc_dev);
 
+free_serial_number:
+       kfree(soc_dev_attr->serial_number);
 free_rev:
        kfree(soc_dev_attr->revision);
 free_soc:
index 089d11f..82e2239 100644 (file)
@@ -6,32 +6,12 @@
 
 #include <linux/errno.h>
 #include <linux/jiffies.h>
+#include <asm/cacheflush.h>
 #include <asm/cp15.h>
 #include <asm/proc-fns.h>
 
 #include "common.h"
 
-static inline void cpu_enter_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile(
-               "mcr    p15, 0, %1, c7, c5, 0\n"
-       "       mcr     p15, 0, %1, c7, c10, 4\n"
-       /*
-        * Turn off coherency
-        */
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       bic     %0, %0, %3\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-       "       mrc     p15, 0, %0, c1, c0, 0\n"
-       "       bic     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-         : "=&r" (v)
-         : "r" (0), "Ir" (CR_C), "Ir" (0x40)
-         : "cc");
-}
-
 /*
  * platform-specific code to shutdown a CPU
  *
@@ -39,7 +19,7 @@ static inline void cpu_enter_lowpower(void)
  */
 void imx_cpu_die(unsigned int cpu)
 {
-       cpu_enter_lowpower();
+       v7_exit_coherency_flush(louis);
        /*
         * We use the cpu jumping argument register to sync with
         * imx_cpu_kill() which is running on cpu0 and waiting for
index 0440109..b58a03b 100644 (file)
@@ -1,13 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menuconfig ARCH_MMP
-       bool "Marvell PXA168/910/MMP2"
+       bool "Marvell PXA168/910/MMP2/MMP3"
        depends on ARCH_MULTI_V5 || ARCH_MULTI_V7
        select GPIO_PXA
        select GPIOLIB
        select PINCTRL
        select PLAT_PXA
        help
-         Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
+         Support for Marvell's PXA168/PXA910(MMP), MMP2, and MMP3 processor lines.
 
 if ARCH_MMP
 
@@ -129,6 +129,24 @@ config MACH_MMP2_DT
          Include support for Marvell MMP2 based platforms using
          the device tree.
 
+config MACH_MMP3_DT
+       bool "Support MMP3 (ARMv7) platforms"
+       depends on ARCH_MULTI_V7
+       select ARM_GIC
+       select HAVE_ARM_SCU if SMP
+       select HAVE_ARM_TWD if SMP
+       select CACHE_L2X0
+       select PINCTRL
+       select PINCTRL_SINGLE
+       select ARCH_HAS_RESET_CONTROLLER
+       select CPU_PJ4B
+       select PM_GENERIC_DOMAINS if PM
+       select PM_GENERIC_DOMAINS_OF if PM && OF
+       help
+         Say 'Y' here if you want to include support for platforms
+         with Marvell MMP3 processor, also known as PXA2128 or
+         Armada 620.
+
 endmenu
 
 config CPU_PXA168
index 8f267c7..7b3a7f9 100644 (file)
@@ -22,6 +22,9 @@ ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_CPU_PXA910)       += pm-pxa910.o
 obj-$(CONFIG_CPU_MMP2)         += pm-mmp2.o
 endif
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_MACH_MMP3_DT)     += platsmp.o
+endif
 
 # board support
 obj-$(CONFIG_MACH_ASPENITE)    += aspenite.o
@@ -34,5 +37,6 @@ obj-$(CONFIG_MACH_FLINT)      += flint.o
 obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
 obj-$(CONFIG_MACH_MMP_DT)      += mmp-dt.o
 obj-$(CONFIG_MACH_MMP2_DT)     += mmp2-dt.o
+obj-$(CONFIG_MACH_MMP3_DT)     += mmp3.o
 obj-$(CONFIG_MACH_TETON_BGA)   += teton_bga.o
 obj-$(CONFIG_MACH_GPLUGD)      += gplugd.o
index 25edf6a..3dc2f0b 100644 (file)
 #define AXI_VIRT_BASE          IOMEM(0xfe200000)
 #define AXI_PHYS_SIZE          0x00200000
 
+#define PGU_PHYS_BASE          0xe0000000
+#define PGU_VIRT_BASE          IOMEM(0xfe400000)
+#define PGU_PHYS_SIZE          0x00100000
+
 /* Static Memory Controller - Chip Select 0 and 1 */
 #define SMC_CS0_PHYS_BASE      0x80000000
 #define SMC_CS0_PHYS_SIZE      0x10000000
@@ -38,4 +42,7 @@
 #define CIU_VIRT_BASE          (AXI_VIRT_BASE + 0x82c00)
 #define CIU_REG(x)             (CIU_VIRT_BASE + (x))
 
+#define SCU_VIRT_BASE          (PGU_VIRT_BASE)
+#define SCU_REG(x)             (SCU_VIRT_BASE + (x))
+
 #endif /* __ASM_MACH_ADDR_MAP_H */
index 6684abc..e94349d 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
 #include "addr-map.h"
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 
 #include "common.h"
 
-#define MMP_CHIPID     (AXI_VIRT_BASE + 0x82c00)
+#define MMP_CHIPID     CIU_REG(0x00)
 
 unsigned int mmp_chip_id;
 EXPORT_SYMBOL(mmp_chip_id);
@@ -36,6 +36,15 @@ static struct map_desc standard_io_desc[] __initdata = {
        },
 };
 
+static struct map_desc mmp2_io_desc[] __initdata = {
+       {
+               .pfn            = __phys_to_pfn(PGU_PHYS_BASE),
+               .virtual        = (unsigned long)PGU_VIRT_BASE,
+               .length         = PGU_PHYS_SIZE,
+               .type           = MT_DEVICE,
+       },
+};
+
 void __init mmp_map_io(void)
 {
        iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
@@ -44,6 +53,12 @@ void __init mmp_map_io(void)
        mmp_chip_id = __raw_readl(MMP_CHIPID);
 }
 
+void __init mmp2_map_io(void)
+{
+       mmp_map_io();
+       iotable_init(mmp2_io_desc, ARRAY_SIZE(mmp2_io_desc));
+}
+
 void mmp_restart(enum reboot_mode mode, const char *cmd)
 {
        soft_restart(0);
index 483b8b6..ed56b3f 100644 (file)
@@ -5,4 +5,5 @@
 extern void mmp_timer_init(int irq, unsigned long rate);
 
 extern void __init mmp_map_io(void);
+extern void __init mmp2_map_io(void);
 extern void mmp_restart(enum reboot_mode, const char *);
index 130c1a6..18bee66 100644 (file)
@@ -11,7 +11,7 @@
 #include <asm/irq.h>
 #include "irqs.h"
 #include "devices.h"
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 #include "regs-usb.h"
 
 int __init pxa_register_device(struct pxa_device_desc *desc,
index 3555979..9121499 100644 (file)
@@ -9,14 +9,13 @@
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/cache-tauros2.h>
 
 #include "common.h"
 
-extern void __init mmp_dt_init_timer(void);
-
 static const char *const pxa168_dt_board_compat[] __initconst = {
        "mrvl,pxa168-aspenite",
        NULL,
@@ -32,8 +31,8 @@ static void __init mmp_init_time(void)
 #ifdef CONFIG_CACHE_TAUROS2
        tauros2_init(0);
 #endif
-       mmp_dt_init_timer();
        of_clk_init(NULL);
+       timer_probe();
 }
 
 DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
index 305a9da..510c762 100644 (file)
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/cache-tauros2.h>
 
 #include "common.h"
 
-extern void __init mmp_dt_init_timer(void);
-
 static void __init mmp_init_time(void)
 {
 #ifdef CONFIG_CACHE_TAUROS2
        tauros2_init(0);
 #endif
        of_clk_init(NULL);
-       mmp_dt_init_timer();
+       timer_probe();
 }
 
 static const char *const mmp2_dt_board_compat[] __initconst = {
@@ -33,7 +32,7 @@ static const char *const mmp2_dt_board_compat[] __initconst = {
 };
 
 DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)")
-       .map_io         = mmp_map_io,
+       .map_io         = mmp2_map_io,
        .init_time      = mmp_init_time,
        .dt_compat      = mmp2_dt_board_compat,
 MACHINE_END
index 18ea3e1..bbc4c22 100644 (file)
@@ -20,7 +20,7 @@
 #include <asm/mach/time.h>
 #include "addr-map.h"
 #include "regs-apbc.h"
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 #include "irqs.h"
 #include "mfp.h"
 #include "devices.h"
diff --git a/arch/arm/mach-mmp/mmp3.c b/arch/arm/mach-mmp/mmp3.c
new file mode 100644 (file)
index 0000000..b0e8696
--- /dev/null
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Marvell MMP3 aka PXA2128 aka 88AP2128 support
+ *
+ *  Copyright (C) 2019 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "common.h"
+
+static const char *const mmp3_dt_board_compat[] __initconst = {
+       "marvell,mmp3",
+       NULL,
+};
+
+DT_MACHINE_START(MMP2_DT, "Marvell MMP3")
+       .map_io         = mmp2_map_io,
+       .dt_compat      = mmp3_dt_board_compat,
+       .l2c_aux_val    = 1 << L310_AUX_CTRL_FWA_SHIFT |
+                         L310_AUX_CTRL_DATA_PREFETCH |
+                         L310_AUX_CTRL_INSTR_PREFETCH,
+       .l2c_aux_mask   = 0xc20fffff,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/platsmp.c b/arch/arm/mach-mmp/platsmp.c
new file mode 100644 (file)
index 0000000..c994054
--- /dev/null
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Lubomir Rintel <lkundrak@v3.sk>
+ */
+#include <linux/io.h>
+#include <asm/smp_scu.h>
+#include <asm/smp.h>
+#include "addr-map.h"
+
+#define SW_BRANCH_VIRT_ADDR    CIU_REG(0x24)
+
+static int mmp3_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       /*
+        * Apparently, the boot ROM on the second core spins on this
+        * register becoming non-zero and then jumps to the address written
+        * there. No IPIs involved.
+        */
+       __raw_writel(__pa_symbol(secondary_startup), SW_BRANCH_VIRT_ADDR);
+       return 0;
+}
+
+static void mmp3_smp_prepare_cpus(unsigned int max_cpus)
+{
+       scu_enable(SCU_VIRT_BASE);
+}
+
+static const struct smp_operations mmp3_smp_ops __initconst = {
+       .smp_prepare_cpus       = mmp3_smp_prepare_cpus,
+       .smp_boot_secondary     = mmp3_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(mmp3_smp, "marvell,mmp3-smp", &mmp3_smp_ops);
index 2923dd5..2d86381 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/interrupt.h>
 #include <asm/mach-types.h>
 
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 #include "addr-map.h"
 #include "pm-mmp2.h"
 #include "regs-icu.h"
index 58535ce..69ebe18 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/mach-types.h>
 #include <asm/outercache.h>
 
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 #include "addr-map.h"
 #include "pm-pxa910.h"
 #include "regs-icu.h"
index 6e02774..b642e90 100644 (file)
@@ -21,7 +21,7 @@
 #include "addr-map.h"
 #include "clock.h"
 #include "common.h"
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 #include "devices.h"
 #include "irqs.h"
 #include "mfp.h"
index 0331c58..dff651b 100644 (file)
@@ -17,9 +17,9 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include <linux/platform_data/keypad-pxa27x.h>
 #include <linux/pxa168_eth.h>
 #include <linux/platform_data/mv_usb.h>
+#include <linux/soc/mmp/cputype.h>
 
 #include "devices.h"
-#include "cputype.h"
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
index cba31c7..b19a069 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/mach/time.h>
 #include "addr-map.h"
 #include "regs-apbc.h"
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 #include "irqs.h"
 #include "mfp.h"
 #include "devices.h"
index d9f08c1..ed0d1aa 100644 (file)
 
 #define UTMI_OTG_ADDON_OTG_ON                  (1 << 0)
 
-/* For MMP3 USB Phy */
-#define USB2_PLL_REG0          0x4
-#define USB2_PLL_REG1          0x8
-#define USB2_TX_REG0           0x10
-#define USB2_TX_REG1           0x14
-#define USB2_TX_REG2           0x18
-#define USB2_RX_REG0           0x20
-#define USB2_RX_REG1           0x24
-#define USB2_RX_REG2           0x28
-#define USB2_ANA_REG0          0x30
-#define USB2_ANA_REG1          0x34
-#define USB2_ANA_REG2          0x38
-#define USB2_DIG_REG0          0x3C
-#define USB2_DIG_REG1          0x40
-#define USB2_DIG_REG2          0x44
-#define USB2_DIG_REG3          0x48
-#define USB2_TEST_REG0         0x4C
-#define USB2_TEST_REG1         0x50
-#define USB2_TEST_REG2         0x54
-#define USB2_CHARGER_REG0      0x58
-#define USB2_OTG_REG0          0x5C
-#define USB2_PHY_MON0          0x60
-#define USB2_RESETVE_REG0      0x64
-#define USB2_ICID_REG0         0x78
-#define USB2_ICID_REG1         0x7C
-
-/* USB2_PLL_REG0 */
-/* This is for Ax stepping */
-#define USB2_PLL_FBDIV_SHIFT_MMP3              0
-#define USB2_PLL_FBDIV_MASK_MMP3               (0xFF << 0)
-
-#define USB2_PLL_REFDIV_SHIFT_MMP3             8
-#define USB2_PLL_REFDIV_MASK_MMP3              (0xF << 8)
-
-#define USB2_PLL_VDD12_SHIFT_MMP3              12
-#define USB2_PLL_VDD18_SHIFT_MMP3              14
-
-/* This is for B0 stepping */
-#define USB2_PLL_FBDIV_SHIFT_MMP3_B0           0
-#define USB2_PLL_REFDIV_SHIFT_MMP3_B0          9
-#define USB2_PLL_VDD18_SHIFT_MMP3_B0           14
-#define USB2_PLL_FBDIV_MASK_MMP3_B0            0x01FF
-#define USB2_PLL_REFDIV_MASK_MMP3_B0           0x3E00
-
-#define USB2_PLL_CAL12_SHIFT_MMP3              0
-#define USB2_PLL_CALI12_MASK_MMP3              (0x3 << 0)
-
-#define USB2_PLL_VCOCAL_START_SHIFT_MMP3       2
-
-#define USB2_PLL_KVCO_SHIFT_MMP3               4
-#define USB2_PLL_KVCO_MASK_MMP3                        (0x7<<4)
-
-#define USB2_PLL_ICP_SHIFT_MMP3                        8
-#define USB2_PLL_ICP_MASK_MMP3                 (0x7<<8)
-
-#define USB2_PLL_LOCK_BYPASS_SHIFT_MMP3                12
-
-#define USB2_PLL_PU_PLL_SHIFT_MMP3             13
-#define USB2_PLL_PU_PLL_MASK                   (0x1 << 13)
-
-#define USB2_PLL_READY_MASK_MMP3               (0x1 << 15)
-
-/* USB2_TX_REG0 */
-#define USB2_TX_IMPCAL_VTH_SHIFT_MMP3          8
-#define USB2_TX_IMPCAL_VTH_MASK_MMP3           (0x7 << 8)
-
-#define USB2_TX_RCAL_START_SHIFT_MMP3          13
-
-/* USB2_TX_REG1 */
-#define USB2_TX_CK60_PHSEL_SHIFT_MMP3          0
-#define USB2_TX_CK60_PHSEL_MASK_MMP3           (0xf << 0)
-
-#define USB2_TX_AMP_SHIFT_MMP3                 4
-#define USB2_TX_AMP_MASK_MMP3                  (0x7 << 4)
-
-#define USB2_TX_VDD12_SHIFT_MMP3               8
-#define USB2_TX_VDD12_MASK_MMP3                        (0x3 << 8)
-
-/* USB2_TX_REG2 */
-#define USB2_TX_DRV_SLEWRATE_SHIFT             10
-
-/* USB2_RX_REG0 */
-#define USB2_RX_SQ_THRESH_SHIFT_MMP3           4
-#define USB2_RX_SQ_THRESH_MASK_MMP3            (0xf << 4)
-
-#define USB2_RX_SQ_LENGTH_SHIFT_MMP3           10
-#define USB2_RX_SQ_LENGTH_MASK_MMP3            (0x3 << 10)
-
-/* USB2_ANA_REG1*/
-#define USB2_ANA_PU_ANA_SHIFT_MMP3             14
-
-/* USB2_OTG_REG0 */
-#define USB2_OTG_PU_OTG_SHIFT_MMP3             3
-
 /* fsic registers */
 #define FSIC_MISC                      0x4
 #define FSIC_INT                       0x28
index 483df32..110dcb3 100644 (file)
@@ -33,7 +33,7 @@
 #include "regs-timers.h"
 #include "regs-apbc.h"
 #include "irqs.h"
-#include "cputype.h"
+#include <linux/soc/mmp/cputype.h>
 #include "clock.h"
 
 #define TIMERS_VIRT_BASE       TIMERS1_VIRT_BASE
@@ -155,7 +155,8 @@ static void __init timer_config(void)
 
        __raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */
 
-       ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
+       ccr &= (cpu_is_mmp2() || cpu_is_mmp3()) ?
+               (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
                (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
        __raw_writel(ccr, mmp_timer_base + TMR_CCR);
 
@@ -195,30 +196,17 @@ void __init mmp_timer_init(int irq, unsigned long rate)
        clockevents_config_and_register(&ckevt, rate, MIN_DELTA, MAX_DELTA);
 }
 
-#ifdef CONFIG_OF
-static const struct of_device_id mmp_timer_dt_ids[] = {
-       { .compatible = "mrvl,mmp-timer", },
-       {}
-};
-
-void __init mmp_dt_init_timer(void)
+static int __init mmp_dt_init_timer(struct device_node *np)
 {
-       struct device_node *np;
        struct clk *clk;
        int irq, ret;
        unsigned long rate;
 
-       np = of_find_matching_node(NULL, mmp_timer_dt_ids);
-       if (!np) {
-               ret = -ENODEV;
-               goto out;
-       }
-
        clk = of_clk_get(np, 0);
        if (!IS_ERR(clk)) {
                ret = clk_prepare_enable(clk);
                if (ret)
-                       goto out;
+                       return ret;
                rate = clk_get_rate(clk) / 2;
        } else if (cpu_is_pj4()) {
                rate = 6500000;
@@ -227,18 +215,15 @@ void __init mmp_dt_init_timer(void)
        }
 
        irq = irq_of_parse_and_map(np, 0);
-       if (!irq) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (!irq)
+               return -EINVAL;
+
        mmp_timer_base = of_iomap(np, 0);
-       if (!mmp_timer_base) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!mmp_timer_base)
+               return -ENOMEM;
+
        mmp_timer_init(irq, rate);
-       return;
-out:
-       pr_err("Failed to get timer from device tree with error:%d\n", ret);
+       return 0;
 }
-#endif
+
+TIMER_OF_DECLARE(mmp_timer, "mrvl,mmp-timer", mmp_dt_init_timer);
index 2a17dc1..948da55 100644 (file)
@@ -4,30 +4,25 @@ if ARCH_OMAP1
 menu "TI OMAP1 specific features"
 
 comment "OMAP Core Type"
-       depends on ARCH_OMAP1
 
 config ARCH_OMAP730
-       depends on ARCH_OMAP1
        bool "OMAP730 Based System"
        select ARCH_OMAP_OTG
        select CPU_ARM926T
        select OMAP_MPU_TIMER
 
 config ARCH_OMAP850
-       depends on ARCH_OMAP1
        bool "OMAP850 Based System"
        select ARCH_OMAP_OTG
        select CPU_ARM926T
 
 config ARCH_OMAP15XX
-       depends on ARCH_OMAP1
        default y
        bool "OMAP15xx Based System"
        select CPU_ARM925T
        select OMAP_MPU_TIMER
 
 config ARCH_OMAP16XX
-       depends on ARCH_OMAP1
        bool "OMAP16xx Based System"
        select ARCH_OMAP_OTG
        select CPU_ARM926T
@@ -35,7 +30,6 @@ config ARCH_OMAP16XX
 
 config OMAP_MUX
        bool "OMAP multiplexing support"
-       depends on ARCH_OMAP
        default y
        help
          Pin multiplexing support for OMAP boards. If your bootloader
@@ -60,25 +54,24 @@ config OMAP_MUX_WARNINGS
          printed, it's safe to deselect OMAP_MUX for your product.
 
 comment "OMAP Board Type"
-       depends on ARCH_OMAP1
 
 config MACH_OMAP_INNOVATOR
        bool "TI Innovator"
-       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
+       depends on ARCH_OMAP15XX || ARCH_OMAP16XX
        help
           TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
           have such a board.
 
 config MACH_OMAP_H2
        bool "TI H2 Support"
-       depends on ARCH_OMAP1 && ARCH_OMAP16XX
+       depends on ARCH_OMAP16XX
        help
          TI OMAP 1610/1611B H2 board support. Say Y here if you have such
          a board.
 
 config MACH_OMAP_H3
        bool "TI H3 Support"
-       depends on ARCH_OMAP1 && ARCH_OMAP16XX
+       depends on ARCH_OMAP16XX
        help
          TI OMAP 1710 H3 board support. Say Y here if you have such
          a board.
@@ -91,7 +84,7 @@ config MACH_HERALD
 
 config MACH_OMAP_OSK
        bool "TI OSK Support"
-       depends on ARCH_OMAP1 && ARCH_OMAP16XX
+       depends on ARCH_OMAP16XX
        help
          TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
           if you have such a board.
@@ -106,21 +99,21 @@ config OMAP_OSK_MISTRAL
 
 config MACH_OMAP_PERSEUS2
        bool "TI Perseus2"
-       depends on ARCH_OMAP1 && ARCH_OMAP730
+       depends on ARCH_OMAP730
        help
          Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
          a board.
 
 config MACH_OMAP_FSAMPLE
        bool "TI F-Sample"
-       depends on ARCH_OMAP1 && ARCH_OMAP730
+       depends on ARCH_OMAP730
        help
          Support for TI OMAP 850 F-Sample board. Say Y here if you have such
          a board.
 
 config MACH_OMAP_PALMTE
        bool "Palm Tungsten E"
-       depends on ARCH_OMAP1 && ARCH_OMAP15XX
+       depends on ARCH_OMAP15XX
        help
          Support for the Palm Tungsten E PDA.  To boot the kernel, you'll
          need a PalmOS compatible bootloader; check out
@@ -129,7 +122,7 @@ config MACH_OMAP_PALMTE
 
 config MACH_OMAP_PALMZ71
        bool "Palm Zire71"
-       depends on ARCH_OMAP1 && ARCH_OMAP15XX
+       depends on ARCH_OMAP15XX
        help
         Support for the Palm Zire71 PDA. To boot the kernel,
         you'll need a PalmOS compatible bootloader; check out
@@ -138,7 +131,7 @@ config MACH_OMAP_PALMZ71
 
 config MACH_OMAP_PALMTT
        bool "Palm Tungsten|T"
-       depends on ARCH_OMAP1 && ARCH_OMAP15XX
+       depends on ARCH_OMAP15XX
        help
          Support for the Palm Tungsten|T PDA. To boot the kernel, you'll
          need a PalmOS compatible bootloader (Garux); check out
@@ -147,7 +140,7 @@ config MACH_OMAP_PALMTT
 
 config MACH_SX1
        bool "Siemens SX1"
-       depends on ARCH_OMAP1 && ARCH_OMAP15XX
+       depends on ARCH_OMAP15XX
        select I2C
        help
          Support for the Siemens SX1 phone. To boot the kernel,
@@ -159,14 +152,14 @@ config MACH_SX1
 
 config MACH_NOKIA770
        bool "Nokia 770"
-       depends on ARCH_OMAP1 && ARCH_OMAP16XX
+       depends on ARCH_OMAP16XX
        help
          Support for the Nokia 770 Internet Tablet. Say Y here if you
          have such a device.
 
 config MACH_AMS_DELTA
        bool "Amstrad E3 (Delta)"
-       depends on ARCH_OMAP1 && ARCH_OMAP15XX
+       depends on ARCH_OMAP15XX
        select FIQ
        select GPIO_GENERIC_PLATFORM
        select LEDS_GPIO_REGISTER
@@ -178,7 +171,7 @@ config MACH_AMS_DELTA
 
 config MACH_OMAP_GENERIC
        bool "Generic OMAP board"
-       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
+       depends on ARCH_OMAP15XX || ARCH_OMAP16XX
        help
           Support for generic OMAP-1510, 1610 or 1710 board with
           no FPGA. Can be used as template for porting Linux to
index 0254eb9..4eea3e3 100644 (file)
@@ -110,7 +110,7 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip,
 
                /*
                 * FIQ handler takes full control over serio data and clk GPIO
-                * pins.  Initiaize them and keep requested so nobody can
+                * pins.  Initialize them and keep requested so nobody can
                 * interfere.  Fail if any of those two couldn't be requested.
                 */
                switch (i) {
index fdb6743..ad08d47 100644 (file)
@@ -109,6 +109,7 @@ config ARCH_OMAP2PLUS
        select TI_SYSC
        select OMAP_IRQCHIP
        select CLKSRC_TI_32K
+       select ARCH_HAS_RESET_CONTROLLER
        help
          Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
 
index 1e1e86d..f07cfda 100644 (file)
@@ -29,6 +29,11 @@ obj-y += mcbsp.o
 endif
 
 obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+
+ifneq ($(CONFIG_MFD_CPCAP),)
+obj-y                                  += pmic-cpcap.o
+endif
+
 obj-$(CONFIG_SOC_HAS_OMAP2_SDRC)       += sdrc.o
 
 # SMP support ONLY available for OMAP4
index f98c8ec..dedd47e 100644 (file)
@@ -1147,7 +1147,21 @@ void clkdm_del_autodeps(struct clockdomain *clkdm)
 
 /* Clockdomain-to-clock/hwmod framework interface code */
 
-static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
+/**
+ * clkdm_clk_enable - add an enabled downstream clock to this clkdm
+ * @clkdm: struct clockdomain *
+ * @clk: struct clk * of the enabled downstream clock
+ *
+ * Increment the usecount of the clockdomain @clkdm and ensure that it
+ * is awake before @clk is enabled.  Intended to be called by
+ * clk_enable() code.  If the clockdomain is in software-supervised
+ * idle mode, force the clockdomain to wake.  If the clockdomain is in
+ * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
+ * ensure that devices in the clockdomain can be read from/written to
+ * by on-chip processors.  Returns -EINVAL if passed null pointers;
+ * returns 0 upon success or if the clockdomain is in hwsup idle mode.
+ */
+int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *unused)
 {
        if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
                return -EINVAL;
@@ -1175,33 +1189,6 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
 }
 
 /**
- * clkdm_clk_enable - add an enabled downstream clock to this clkdm
- * @clkdm: struct clockdomain *
- * @clk: struct clk * of the enabled downstream clock
- *
- * Increment the usecount of the clockdomain @clkdm and ensure that it
- * is awake before @clk is enabled.  Intended to be called by
- * clk_enable() code.  If the clockdomain is in software-supervised
- * idle mode, force the clockdomain to wake.  If the clockdomain is in
- * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
- * ensure that devices in the clockdomain can be read from/written to
- * by on-chip processors.  Returns -EINVAL if passed null pointers;
- * returns 0 upon success or if the clockdomain is in hwsup idle mode.
- */
-int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
-{
-       /*
-        * XXX Rewrite this code to maintain a list of enabled
-        * downstream clocks for debugging purposes?
-        */
-
-       if (!clk)
-               return -EINVAL;
-
-       return _clkdm_clk_hwmod_enable(clkdm);
-}
-
-/**
  * clkdm_clk_disable - remove an enabled downstream clock from this clkdm
  * @clkdm: struct clockdomain *
  * @clk: struct clk * of the disabled downstream clock
@@ -1216,13 +1203,13 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
  */
 int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
 {
-       if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
+       if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
                return -EINVAL;
 
        pwrdm_lock(clkdm->pwrdm.ptr);
 
        /* corner case: disabling unused clocks */
-       if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)
+       if (clk && (__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)
                goto ccd_exit;
 
        if (clkdm->usecount == 0) {
@@ -1277,7 +1264,7 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
        if (!oh)
                return -EINVAL;
 
-       return _clkdm_clk_hwmod_enable(clkdm);
+       return clkdm_clk_enable(clkdm, NULL);
 }
 
 /**
@@ -1300,35 +1287,10 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
        if (cpu_is_omap24xx() || cpu_is_omap34xx())
                return 0;
 
-       /*
-        * XXX Rewrite this code to maintain a list of enabled
-        * downstream hwmods for debugging purposes?
-        */
-
-       if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
+       if (!oh)
                return -EINVAL;
 
-       pwrdm_lock(clkdm->pwrdm.ptr);
-
-       if (clkdm->usecount == 0) {
-               pwrdm_unlock(clkdm->pwrdm.ptr);
-               WARN_ON(1); /* underflow */
-               return -ERANGE;
-       }
-
-       clkdm->usecount--;
-       if (clkdm->usecount > 0) {
-               pwrdm_unlock(clkdm->pwrdm.ptr);
-               return 0;
-       }
-
-       arch_clkdm->clkdm_clk_disable(clkdm);
-       pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
-       pwrdm_unlock(clkdm->pwrdm.ptr);
-
-       pr_debug("clockdomain: %s: disabled\n", clkdm->name);
-
-       return 0;
+       return clkdm_clk_disable(clkdm, NULL);
 }
 
 /**
index c84b5e2..73338cf 100644 (file)
@@ -684,7 +684,7 @@ static u32 am33xx_control_vals[ARRAY_SIZE(am43xx_control_reg_offsets)];
  *
  * Save the wkup domain registers
  */
-void am43xx_control_save_context(void)
+static void am43xx_control_save_context(void)
 {
        int i;
 
@@ -698,7 +698,7 @@ void am43xx_control_save_context(void)
  *
  * Restore the wkup domain registers
  */
-void am43xx_control_restore_context(void)
+static void am43xx_control_restore_context(void)
 {
        int i;
 
index 393b421..eceb4b0 100644 (file)
 #define OMAP44XX_CONTROL_FUSE_MPU_OPP100       0x243
 #define OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO     0x246
 #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO     0x249
+#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITROSB   0x24C
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP50       0x254
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP100      0x257
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV    0x25A
index 439e143..46012ca 100644 (file)
@@ -265,6 +265,7 @@ static int __init omapdss_init_of(void)
        r = of_platform_populate(node, NULL, NULL, &pdev->dev);
        if (r) {
                pr_err("Unable to populate DSS submodule devices\n");
+               put_device(&pdev->dev);
                return r;
        }
 
index 2d8f905..67fa285 100644 (file)
@@ -227,7 +227,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 {
        struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
        unsigned int save_state = 0, cpu_logic_state = PWRDM_POWER_RET;
-       unsigned int wakeup_cpu;
 
        if (omap_rev() == OMAP4430_REV_ES1_0)
                return -ENXIO;
@@ -292,7 +291,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
         * secure devices, CPUx does WFI which can result in
         * domain transition
         */
-       wakeup_cpu = smp_processor_id();
        pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
 
        pwrdm_post_transition(NULL);
index 3acb419..1d55602 100644 (file)
@@ -119,11 +119,7 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,
 
 /**
  * omap_device_build_from_dt - build an omap_device with multiple hwmods
- * @pdev_name: name of the platform_device driver to use
- * @pdev_id: this platform_device's connection ID
- * @oh: ptr to the single omap_hwmod that backs this omap_device
- * @pdata: platform_data ptr to associate with the platform_device
- * @pdata_len: amount of memory pointed to by @pdata
+ * @pdev: The platform device to update.
  *
  * Function for building an omap_device already registered from device-tree
  *
@@ -292,7 +288,7 @@ static int _omap_device_idle_hwmods(struct omap_device *od)
 
 /**
  * omap_device_get_context_loss_count - get lost context count
- * @od: struct omap_device *
+ * @pdev: The platform device to update.
  *
  * Using the primary hwmod, query the context loss count for this
  * device.
@@ -321,9 +317,8 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
 /**
  * omap_device_alloc - allocate an omap_device
  * @pdev: platform_device that will be included in this omap_device
- * @oh: ptr to the single omap_hwmod that backs this omap_device
- * @pdata: platform_data ptr to associate with the platform_device
- * @pdata_len: amount of memory pointed to by @pdata
+ * @ohs: ptr to the omap_hwmod for this omap_device
+ * @oh_cnt: the size of the ohs list
  *
  * Convenience function for allocating an omap_device structure and filling
  * hwmods, and resources.
@@ -649,7 +644,7 @@ struct dev_pm_domain omap_device_pm_domain = {
 
 /**
  * omap_device_register - register an omap_device with one omap_hwmod
- * @od: struct omap_device * to register
+ * @pdev: the platform device (omap_device) to register.
  *
  * Register the omap_device structure.  This currently just calls
  * platform_device_register() on the underlying platform_device.
@@ -668,7 +663,7 @@ int omap_device_register(struct platform_device *pdev)
 
 /**
  * omap_device_enable - fully activate an omap_device
- * @od: struct omap_device * to activate
+ * @pdev: the platform device to activate
  *
  * Do whatever is necessary for the hwmods underlying omap_device @od
  * to be accessible and ready to operate.  This generally involves
@@ -702,7 +697,7 @@ int omap_device_enable(struct platform_device *pdev)
 
 /**
  * omap_device_idle - idle an omap_device
- * @od: struct omap_device * to idle
+ * @pdev: The platform_device (omap_device) to idle
  *
  * Idle omap_device @od.  Device drivers call this function indirectly
  * via pm_runtime_put*().  Returns -EINVAL if the omap_device is not
index 203664c..a136788 100644 (file)
@@ -623,39 +623,6 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
        return 0;
 }
 
-/**
- * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
- * @oh: struct omap_hwmod *
- *
- * Prevent the hardware module @oh to send wakeups.  Returns -EINVAL
- * upon error or 0 upon success.
- */
-static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
-{
-       if (!oh->class->sysc ||
-           !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
-             (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
-             (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
-               return -EINVAL;
-
-       if (!oh->class->sysc->sysc_fields) {
-               WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
-               return -EINVAL;
-       }
-
-       if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
-               *v &= ~(0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
-
-       if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
-               _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
-       if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
-               _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v);
-
-       /* XXX test pwrdm_get_wken for this hwmod's subsystem */
-
-       return 0;
-}
-
 static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
 {
        struct clk_hw_omap *clk;
@@ -3868,70 +3835,6 @@ void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
  */
 
 /**
- * omap_hwmod_enable_wakeup - allow device to wake up the system
- * @oh: struct omap_hwmod *
- *
- * Sets the module OCP socket ENAWAKEUP bit to allow the module to
- * send wakeups to the PRCM, and enable I/O ring wakeup events for
- * this IP block if it has dynamic mux entries.  Eventually this
- * should set PRCM wakeup registers to cause the PRCM to receive
- * wakeup events from the module.  Does not set any wakeup routing
- * registers beyond this point - if the module is to wake up any other
- * module or subsystem, that must be set separately.  Called by
- * omap_device code.  Returns -EINVAL on error or 0 upon success.
- */
-int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
-{
-       unsigned long flags;
-       u32 v;
-
-       spin_lock_irqsave(&oh->_lock, flags);
-
-       if (oh->class->sysc &&
-           (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
-               v = oh->_sysc_cache;
-               _enable_wakeup(oh, &v);
-               _write_sysconfig(v, oh);
-       }
-
-       spin_unlock_irqrestore(&oh->_lock, flags);
-
-       return 0;
-}
-
-/**
- * omap_hwmod_disable_wakeup - prevent device from waking the system
- * @oh: struct omap_hwmod *
- *
- * Clears the module OCP socket ENAWAKEUP bit to prevent the module
- * from sending wakeups to the PRCM, and disable I/O ring wakeup
- * events for this IP block if it has dynamic mux entries.  Eventually
- * this should clear PRCM wakeup registers to cause the PRCM to ignore
- * wakeup events from the module.  Does not set any wakeup routing
- * registers beyond this point - if the module is to wake up any other
- * module or subsystem, that must be set separately.  Called by
- * omap_device code.  Returns -EINVAL on error or 0 upon success.
- */
-int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
-{
-       unsigned long flags;
-       u32 v;
-
-       spin_lock_irqsave(&oh->_lock, flags);
-
-       if (oh->class->sysc &&
-           (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
-               v = oh->_sysc_cache;
-               _disable_wakeup(oh, &v);
-               _write_sysconfig(v, oh);
-       }
-
-       spin_unlock_irqrestore(&oh->_lock, flags);
-
-       return 0;
-}
-
-/**
  * omap_hwmod_assert_hardreset - assert the HW reset line of submodules
  * contained in the hwmod module.
  * @oh: struct omap_hwmod *
index ef1bb08..2d0fd99 100644 (file)
@@ -646,9 +646,6 @@ int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
 struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
 void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
 
-int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
-int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
-
 int omap_hwmod_for_each_by_class(const char *classname,
                                 int (*fn)(struct omap_hwmod *oh,
                                           void *user),
index 3de3d7a..26e13d4 100644 (file)
@@ -35,10 +35,7 @@ extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0;
 extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1;
 extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2;
 extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc;
-extern struct omap_hwmod_ocp_if am33xx_l4_per__mailbox;
 extern struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1;
 extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0;
 extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1;
 extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2;
@@ -54,7 +51,6 @@ extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc2;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__sha0;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__aes0;
-extern struct omap_hwmod_ocp_if am33xx_l4_per__rng;
 
 extern struct omap_hwmod am33xx_l3_main_hwmod;
 extern struct omap_hwmod am33xx_l3_s_hwmod;
@@ -67,7 +63,6 @@ extern struct omap_hwmod am33xx_gfx_hwmod;
 extern struct omap_hwmod am33xx_prcm_hwmod;
 extern struct omap_hwmod am33xx_aes0_hwmod;
 extern struct omap_hwmod am33xx_sha0_hwmod;
-extern struct omap_hwmod am33xx_rng_hwmod;
 extern struct omap_hwmod am33xx_ocmcram_hwmod;
 extern struct omap_hwmod am33xx_smartreflex0_hwmod;
 extern struct omap_hwmod am33xx_smartreflex1_hwmod;
@@ -78,9 +73,6 @@ extern struct omap_hwmod am33xx_epwmss0_hwmod;
 extern struct omap_hwmod am33xx_epwmss1_hwmod;
 extern struct omap_hwmod am33xx_epwmss2_hwmod;
 extern struct omap_hwmod am33xx_gpmc_hwmod;
-extern struct omap_hwmod am33xx_mailbox_hwmod;
-extern struct omap_hwmod am33xx_mcasp0_hwmod;
-extern struct omap_hwmod am33xx_mcasp1_hwmod;
 extern struct omap_hwmod am33xx_rtc_hwmod;
 extern struct omap_hwmod am33xx_spi0_hwmod;
 extern struct omap_hwmod am33xx_spi1_hwmod;
@@ -96,7 +88,6 @@ extern struct omap_hwmod am33xx_tpcc_hwmod;
 extern struct omap_hwmod am33xx_tptc0_hwmod;
 extern struct omap_hwmod am33xx_tptc1_hwmod;
 extern struct omap_hwmod am33xx_tptc2_hwmod;
-extern struct omap_hwmod am33xx_wd_timer1_hwmod;
 
 extern struct omap_hwmod_class am33xx_emif_hwmod_class;
 extern struct omap_hwmod_class am33xx_l4_hwmod_class;
index 63698ff..7123c45 100644 (file)
@@ -158,14 +158,6 @@ struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 ls -> mailbox */
-struct omap_hwmod_ocp_if am33xx_l4_per__mailbox = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mailbox_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4 ls -> spinlock */
 struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = {
        .master         = &am33xx_l4_ls_hwmod,
@@ -174,22 +166,6 @@ struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 ls -> mcasp0 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mcasp0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mcasp1 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_mcasp1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4 ls -> mcspi0 */
 struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = {
        .master         = &am33xx_l4_ls_hwmod,
@@ -308,11 +284,3 @@ struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = {
        .clk            = "aes0_fck",
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
-
-/* l4 per -> rng */
-struct omap_hwmod_ocp_if am33xx_l4_per__rng = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_rng_hwmod,
-       .clk            = "rng_fck",
-       .user           = OCP_USER_MPU,
-};
index 29fd136..2df8659 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 
 #include "omap_hwmod.h"
-#include "wd_timer.h"
 #include "cm33xx.h"
 #include "prm33xx.h"
 #include "omap_hwmod_33xx_43xx_common_data.h"
@@ -266,33 +265,6 @@ struct omap_hwmod am33xx_sha0_hwmod = {
        },
 };
 
-/* rng */
-static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = {
-       .rev_offs       = 0x1fe0,
-       .sysc_offs      = 0x1fe4,
-       .sysc_flags     = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE,
-       .idlemodes      = SIDLE_FORCE | SIDLE_NO,
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_rng_hwmod_class = {
-       .name           = "rng",
-       .sysc           = &am33xx_rng_sysc,
-};
-
-struct omap_hwmod am33xx_rng_hwmod = {
-       .name           = "rng",
-       .class          = &am33xx_rng_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE,
-       .main_clk       = "rng_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /* ocmcram */
 static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
        .name = "ocmcram",
@@ -466,86 +438,6 @@ struct omap_hwmod am33xx_epwmss2_hwmod = {
        },
 };
 
-/*
- * 'gpio' class: for gpio 0,1,2,3
- */
-static struct omap_hwmod_class_sysconfig am33xx_gpio_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0114,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
-                         SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                         SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_gpio_hwmod_class = {
-       .name           = "gpio",
-       .sysc           = &am33xx_gpio_sysc,
-};
-
-/* gpio1 */
-static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
-       { .role = "dbclk", .clk = "gpio1_dbclk" },
-};
-
-static struct omap_hwmod am33xx_gpio1_hwmod = {
-       .name           = "gpio2",
-       .class          = &am33xx_gpio_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = gpio1_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(gpio1_opt_clks),
-};
-
-/* gpio2 */
-static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
-       { .role = "dbclk", .clk = "gpio2_dbclk" },
-};
-
-static struct omap_hwmod am33xx_gpio2_hwmod = {
-       .name           = "gpio3",
-       .class          = &am33xx_gpio_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = gpio2_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(gpio2_opt_clks),
-};
-
-/* gpio3 */
-static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
-       { .role = "dbclk", .clk = "gpio3_dbclk" },
-};
-
-static struct omap_hwmod am33xx_gpio3_hwmod = {
-       .name           = "gpio4",
-       .class          = &am33xx_gpio_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = gpio3_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(gpio3_opt_clks),
-};
-
 /* gpmc */
 static struct omap_hwmod_class_sysconfig gpmc_sysc = {
        .rev_offs       = 0x0,
@@ -576,78 +468,6 @@ struct omap_hwmod am33xx_gpmc_hwmod = {
        },
 };
 
-/*
- * 'mailbox' class
- * mailbox module allowing communication between the on-chip processors using a
- * queued mailbox-interrupt mechanism.
- */
-static struct omap_hwmod_class_sysconfig am33xx_mailbox_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
-                         SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_mailbox_hwmod_class = {
-       .name   = "mailbox",
-       .sysc   = &am33xx_mailbox_sysc,
-};
-
-struct omap_hwmod am33xx_mailbox_hwmod = {
-       .name           = "mailbox",
-       .class          = &am33xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm = {
-               .omap4 = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'mcasp' class
- */
-static struct omap_hwmod_class_sysconfig am33xx_mcasp_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x4,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type3,
-};
-
-static struct omap_hwmod_class am33xx_mcasp_hwmod_class = {
-       .name           = "mcasp",
-       .sysc           = &am33xx_mcasp_sysc,
-};
-
-/* mcasp0 */
-struct omap_hwmod am33xx_mcasp0_hwmod = {
-       .name           = "mcasp0",
-       .class          = &am33xx_mcasp_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .main_clk       = "mcasp0_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* mcasp1 */
-struct omap_hwmod am33xx_mcasp1_hwmod = {
-       .name           = "mcasp1",
-       .class          = &am33xx_mcasp_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .main_clk       = "mcasp1_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /*
  * 'rtc' class
@@ -950,41 +770,6 @@ struct omap_hwmod am33xx_tptc2_hwmod = {
        },
 };
 
-/* 'wd_timer' class */
-static struct omap_hwmod_class_sysconfig wdt_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x10,
-       .syss_offs      = 0x14,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
-                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                       SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = {
-       .name           = "wd_timer",
-       .sysc           = &wdt_sysc,
-       .pre_shutdown   = &omap2_wd_timer_disable,
-};
-
-/*
- * XXX: device.c file uses hardcoded name for watchdog timer
- * driver "wd_timer2, so we are also using same name as of now...
- */
-struct omap_hwmod am33xx_wd_timer1_hwmod = {
-       .name           = "wd_timer2",
-       .class          = &am33xx_wd_timer_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE,
-       .main_clk       = "wdt1_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 static void omap_hwmod_am33xx_clkctrl(void)
 {
        CLKCTRL(am33xx_dcan0_hwmod, AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET);
@@ -993,12 +778,6 @@ static void omap_hwmod_am33xx_clkctrl(void)
        CLKCTRL(am33xx_epwmss0_hwmod, AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_epwmss1_hwmod, AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_epwmss2_hwmod, AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_gpio1_hwmod, AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_gpio2_hwmod, AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_gpio3_hwmod, AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_mailbox_hwmod, AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_mcasp0_hwmod, AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_mcasp1_hwmod, AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_spi0_hwmod, AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_spi1_hwmod, AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_spinlock_hwmod, AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
@@ -1013,7 +792,6 @@ static void omap_hwmod_am33xx_clkctrl(void)
        CLKCTRL(am33xx_smartreflex1_hwmod,
                AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_timer1_hwmod, AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET);
        PRCM_FLAGS(am33xx_rtc_hwmod, HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET);
@@ -1031,7 +809,6 @@ static void omap_hwmod_am33xx_clkctrl(void)
        CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_rng_hwmod, AM33XX_CM_PER_RNG_CLKCTRL_OFFSET);
 }
 
 static void omap_hwmod_am33xx_rst(void)
@@ -1055,12 +832,6 @@ static void omap_hwmod_am43xx_clkctrl(void)
        CLKCTRL(am33xx_epwmss0_hwmod, AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_epwmss1_hwmod, AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_epwmss2_hwmod, AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_gpio1_hwmod, AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_gpio2_hwmod, AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_gpio3_hwmod, AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_mailbox_hwmod, AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_mcasp0_hwmod, AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_mcasp1_hwmod, AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_spi0_hwmod, AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_spi1_hwmod, AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_spinlock_hwmod, AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
@@ -1075,7 +846,6 @@ static void omap_hwmod_am43xx_clkctrl(void)
        CLKCTRL(am33xx_smartreflex1_hwmod,
                AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_timer1_hwmod, AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_wd_timer1_hwmod, AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET);
@@ -1092,7 +862,6 @@ static void omap_hwmod_am43xx_clkctrl(void)
        CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_rng_hwmod, AM43XX_CM_PER_RNG_CLKCTRL_OFFSET);
 }
 
 static void omap_hwmod_am43xx_rst(void)
index 5452477..c63f664 100644 (file)
@@ -21,7 +21,6 @@
 #include "cm33xx.h"
 #include "prm33xx.h"
 #include "prm-regbits-33xx.h"
-#include "wd_timer.h"
 #include "omap_hwmod_33xx_43xx_common_data.h"
 
 /*
@@ -257,39 +256,6 @@ static struct omap_hwmod am33xx_lcdc_hwmod = {
 };
 
 /*
- * 'usb_otg' class
- * high-speed on-the-go universal serial bus (usb_otg) controller
- */
-static struct omap_hwmod_class_sysconfig am33xx_usbhsotg_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x10,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_usbotg_class = {
-       .name           = "usbotg",
-       .sysc           = &am33xx_usbhsotg_sysc,
-};
-
-static struct omap_hwmod am33xx_usbss_hwmod = {
-       .name           = "usb_otg_hs",
-       .class          = &am33xx_usbotg_class,
-       .clkdm_name     = "l3s_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
-       .main_clk       = "usbotg_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_USB0_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-
-/*
  * Interfaces
  */
 
@@ -388,24 +354,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 wkup -> wd_timer1 */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__wd_timer1 = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_wd_timer1_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU,
-};
-
-/* usbss */
-/* l3 s -> USBSS interface */
-static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = {
-       .master         = &am33xx_l3_s_hwmod,
-       .slave          = &am33xx_usbss_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU,
-       .flags          = OCPIF_SWSUP_IDLE,
-};
-
 static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l3_main__emif,
        &am33xx_mpu__l3_main,
@@ -428,13 +376,9 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l4_wkup__timer1,
        &am33xx_l4_wkup__rtc,
        &am33xx_l4_wkup__adc_tsc,
-       &am33xx_l4_wkup__wd_timer1,
        &am33xx_l4_hs__pruss,
        &am33xx_l4_per__dcan0,
        &am33xx_l4_per__dcan1,
-       &am33xx_l4_per__mailbox,
-       &am33xx_l4_ls__mcasp0,
-       &am33xx_l4_ls__mcasp1,
        &am33xx_l4_ls__timer2,
        &am33xx_l4_ls__timer3,
        &am33xx_l4_ls__timer4,
@@ -455,10 +399,8 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l3_main__tptc1,
        &am33xx_l3_main__tptc2,
        &am33xx_l3_main__ocmc,
-       &am33xx_l3_s__usbss,
        &am33xx_l3_main__sha0,
        &am33xx_l3_main__aes0,
-       &am33xx_l4_per__rng,
        NULL,
 };
 
index 5c3db6b..b81f834 100644 (file)
@@ -18,8 +18,6 @@
 #include "omap_hwmod_33xx_43xx_common_data.h"
 #include "prcm43xx.h"
 #include "omap_hwmod_common_data.h"
-#include "hdq1w.h"
-
 
 /* IP blocks */
 static struct omap_hwmod am43xx_emif_hwmod = {
@@ -468,32 +466,6 @@ static struct omap_hwmod am43xx_dss_rfbi_hwmod = {
        .parent_hwmod   = &am43xx_dss_core_hwmod,
 };
 
-/* HDQ1W */
-static struct omap_hwmod_class_sysconfig am43xx_hdq1w_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0014,
-       .syss_offs      = 0x0018,
-       .sysc_flags     = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am43xx_hdq1w_hwmod_class = {
-       .name   = "hdq1w",
-       .sysc   = &am43xx_hdq1w_sysc,
-       .reset  = &omap_hdq1w_reset,
-};
-
-static struct omap_hwmod am43xx_hdq1w_hwmod = {
-       .name           = "hdq1w",
-       .class          = &am43xx_hdq1w_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 static struct omap_hwmod_class_sysconfig am43xx_vpfe_sysc = {
        .rev_offs       = 0x0,
@@ -604,13 +576,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_wkup__timer1 = {
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am43xx_l4_wkup__wd_timer1 = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_wd_timer1_hwmod,
-       .clk            = "sys_clkin_ck",
-       .user           = OCP_USER_MPU,
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = {
        .master         = &am33xx_l4_wkup_hwmod,
        .slave          = &am43xx_synctimer_hwmod,
@@ -751,13 +716,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__dss_rfbi = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_ocp_if am43xx_l4_ls__hdq1w = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_hdq1w_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 static struct omap_hwmod_ocp_if am43xx_l3__vpfe0 = {
        .master         = &am43xx_vpfe0_hwmod,
        .slave          = &am33xx_l3_main_hwmod,
@@ -824,15 +782,10 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
        &am43xx_l4_wkup__smartreflex0,
        &am43xx_l4_wkup__smartreflex1,
        &am43xx_l4_wkup__timer1,
-       &am43xx_l4_wkup__wd_timer1,
        &am43xx_l4_wkup__adc_tsc,
        &am43xx_l3_s__qspi,
        &am33xx_l4_per__dcan0,
        &am33xx_l4_per__dcan1,
-       &am33xx_l4_per__mailbox,
-       &am33xx_l4_per__rng,
-       &am33xx_l4_ls__mcasp0,
-       &am33xx_l4_ls__mcasp1,
        &am33xx_l4_ls__timer2,
        &am33xx_l4_ls__timer3,
        &am33xx_l4_ls__timer4,
@@ -863,7 +816,6 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
        &am43xx_l4_ls__dss,
        &am43xx_l4_ls__dss_dispc,
        &am43xx_l4_ls__dss_rfbi,
-       &am43xx_l4_ls__hdq1w,
        &am43xx_l3__vpfe0,
        &am43xx_l3__vpfe1,
        &am43xx_l4_ls__vpfe0,
index 28ea296..292f544 100644 (file)
@@ -790,7 +790,7 @@ static struct omap_hwmod_class omap44xx_sha0_hwmod_class = {
        .sysc           = &omap44xx_sha0_sysc,
 };
 
-struct omap_hwmod omap44xx_sha0_hwmod = {
+static struct omap_hwmod omap44xx_sha0_hwmod = {
        .name           = "sham",
        .class          = &omap44xx_sha0_hwmod_class,
        .clkdm_name     = "l4_secure_clkdm",
@@ -974,7 +974,7 @@ static struct omap_hwmod omap44xx_des_hwmod = {
        },
 };
 
-struct omap_hwmod_ocp_if omap44xx_l3_main_2__des = {
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__des = {
        .master         = &omap44xx_l3_main_2_hwmod,
        .slave          = &omap44xx_des_hwmod,
        .clk            = "l3_div_ck",
@@ -1061,40 +1061,6 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = {
        },
 };
 
-/*
- * 'hdq1w' class
- * hdq / 1-wire serial interface controller
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_hdq1w_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0014,
-       .syss_offs      = 0x0018,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_hdq1w_hwmod_class = {
-       .name   = "hdq1w",
-       .sysc   = &omap44xx_hdq1w_sysc,
-};
-
-/* hdq1w */
-static struct omap_hwmod omap44xx_hdq1w_hwmod = {
-       .name           = "hdq1w",
-       .class          = &omap44xx_hdq1w_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .flags          = HWMOD_INIT_NO_RESET, /* XXX temporary */
-       .main_clk       = "func_12m_fclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /*
  * 'hsi' class
@@ -1288,180 +1254,6 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {
        },
 };
 
-/*
- * 'mailbox' class
- * mailbox module allowing communication between the on-chip processors using a
- * queued mailbox-interrupt mechanism.
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_mailbox_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap44xx_mailbox_hwmod_class = {
-       .name   = "mailbox",
-       .sysc   = &omap44xx_mailbox_sysc,
-};
-
-/* mailbox */
-static struct omap_hwmod omap44xx_mailbox_hwmod = {
-       .name           = "mailbox",
-       .class          = &omap44xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4_cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
- * 'mcasp' class
- * multi-channel audio serial port controller
- */
-
-/* The IP is not compliant to type1 / type2 scheme */
-static struct omap_hwmod_class_sysconfig omap44xx_mcasp_sysc = {
-       .rev_offs       = 0,
-       .sysc_offs      = 0x0004,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type_mcasp,
-};
-
-static struct omap_hwmod_class omap44xx_mcasp_hwmod_class = {
-       .name   = "mcasp",
-       .sysc   = &omap44xx_mcasp_sysc,
-};
-
-/* mcasp */
-static struct omap_hwmod omap44xx_mcasp_hwmod = {
-       .name           = "mcasp",
-       .class          = &omap44xx_mcasp_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "func_mcasp_abe_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'mcbsp' class
- * multi channel buffered serial port controller
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
-       .rev_offs       = -ENODEV,
-       .sysc_offs      = 0x008c,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = {
-       .name   = "mcbsp",
-       .sysc   = &omap44xx_mcbsp_sysc,
-};
-
-/* mcbsp1 */
-static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = {
-       { .role = "pad_fck", .clk = "pad_clks_ck" },
-       { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" },
-};
-
-static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
-       .name           = "mcbsp1",
-       .class          = &omap44xx_mcbsp_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "func_mcbsp1_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = mcbsp1_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(mcbsp1_opt_clks),
-};
-
-/* mcbsp2 */
-static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = {
-       { .role = "pad_fck", .clk = "pad_clks_ck" },
-       { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" },
-};
-
-static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
-       .name           = "mcbsp2",
-       .class          = &omap44xx_mcbsp_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "func_mcbsp2_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = mcbsp2_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(mcbsp2_opt_clks),
-};
-
-/* mcbsp3 */
-static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = {
-       { .role = "pad_fck", .clk = "pad_clks_ck" },
-       { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" },
-};
-
-static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
-       .name           = "mcbsp3",
-       .class          = &omap44xx_mcbsp_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "func_mcbsp3_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = mcbsp3_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(mcbsp3_opt_clks),
-};
-
-/* mcbsp4 */
-static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = {
-       { .role = "pad_fck", .clk = "pad_clks_ck" },
-       { .role = "prcm_fck", .clk = "mcbsp4_sync_mux_ck" },
-};
-
-static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
-       .name           = "mcbsp4",
-       .class          = &omap44xx_mcbsp_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .main_clk       = "per_mcbsp4_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = mcbsp4_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(mcbsp4_opt_clks),
-};
 
 /*
  * 'mcpdm' class
@@ -2295,51 +2087,6 @@ static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
 };
 
 /*
- * 'usb_otg_hs' class
- * high-speed on-the-go universal serial bus (usb_otg_hs) controller
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_usb_otg_hs_sysc = {
-       .rev_offs       = 0x0400,
-       .sysc_offs      = 0x0404,
-       .syss_offs      = 0x0408,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
-                          SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
-                          MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_usb_otg_hs_hwmod_class = {
-       .name   = "usb_otg_hs",
-       .sysc   = &omap44xx_usb_otg_hs_sysc,
-};
-
-/* usb_otg_hs */
-static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = {
-       { .role = "xclk", .clk = "usb_otg_hs_xclk" },
-};
-
-static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
-       .name           = "usb_otg_hs",
-       .class          = &omap44xx_usb_otg_hs_hwmod_class,
-       .clkdm_name     = "l3_init_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
-       .main_clk       = "usb_otg_hs_ick",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-       .opt_clks       = usb_otg_hs_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(usb_otg_hs_opt_clks),
-};
-
-/*
  * 'usb_tll_hs' class
  * usb_tll_hs module is the adapter on the usb_host_hs ports
  */
@@ -2546,14 +2293,6 @@ static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* usb_otg_hs -> l3_main_2 */
-static struct omap_hwmod_ocp_if omap44xx_usb_otg_hs__l3_main_2 = {
-       .master         = &omap44xx_usb_otg_hs_hwmod,
-       .slave          = &omap44xx_l3_main_2_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_1 -> l3_main_3 */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = {
        .master         = &omap44xx_l3_main_1_hwmod,
@@ -2898,14 +2637,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_per -> hdq1w */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__hdq1w = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_hdq1w_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_cfg -> hsi */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__hsi = {
        .master         = &omap44xx_l4_cfg_hwmod,
@@ -2954,62 +2685,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_wkup__kbd = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> mailbox */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mailbox = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_mailbox_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> mcasp */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_mcasp_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> mcasp (dma) */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp_dma = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_mcasp_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_SDMA,
-};
-
-/* l4_abe -> mcbsp1 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_mcbsp1_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> mcbsp2 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_mcbsp2_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> mcbsp3 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_mcbsp3_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> mcbsp4 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_mcbsp4_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_abe -> mcpdm */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = {
        .master         = &omap44xx_l4_abe_hwmod,
@@ -3242,14 +2917,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> usb_otg_hs */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_otg_hs = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_usb_otg_hs_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_cfg -> usb_tll_hs */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = {
        .master         = &omap44xx_l4_cfg_hwmod,
@@ -3296,7 +2963,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
        &omap44xx_l4_cfg__l3_main_2,
        /* &omap44xx_usb_host_fs__l3_main_2, */
        &omap44xx_usb_host_hs__l3_main_2,
-       &omap44xx_usb_otg_hs__l3_main_2,
        &omap44xx_l3_main_1__l3_main_3,
        &omap44xx_l3_main_2__l3_main_3,
        &omap44xx_l4_cfg__l3_main_3,
@@ -3339,20 +3005,12 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
        &omap44xx_l4_per__elm,
        &omap44xx_l4_cfg__fdif,
        &omap44xx_l3_main_2__gpmc,
-       &omap44xx_l4_per__hdq1w,
        &omap44xx_l4_cfg__hsi,
        &omap44xx_l3_main_2__ipu,
        &omap44xx_l3_main_2__iss,
        /* &omap44xx_iva__sl2if, */
        &omap44xx_l3_main_2__iva,
        &omap44xx_l4_wkup__kbd,
-       &omap44xx_l4_cfg__mailbox,
-       &omap44xx_l4_abe__mcasp,
-       &omap44xx_l4_abe__mcasp_dma,
-       &omap44xx_l4_abe__mcbsp1,
-       &omap44xx_l4_abe__mcbsp2,
-       &omap44xx_l4_abe__mcbsp3,
-       &omap44xx_l4_per__mcbsp4,
        &omap44xx_l4_abe__mcpdm,
        &omap44xx_l3_main_2__mmu_ipu,
        &omap44xx_l4_cfg__mmu_dsp,
@@ -3384,7 +3042,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
        &omap44xx_l4_per__timer11,
        /* &omap44xx_l4_cfg__usb_host_fs, */
        &omap44xx_l4_cfg__usb_host_hs,
-       &omap44xx_l4_cfg__usb_otg_hs,
        &omap44xx_l4_cfg__usb_tll_hs,
        &omap44xx_mpu__emif1,
        &omap44xx_mpu__emif2,
index 8006b43..cc5ad6a 100644 (file)
@@ -24,7 +24,6 @@
 #include "cm1_54xx.h"
 #include "cm2_54xx.h"
 #include "prm54xx.h"
-#include "wd_timer.h"
 
 /* Base offset for all OMAP5 interrupts external to MPUSS */
 #define OMAP54XX_IRQ_GIC_START 32
@@ -629,124 +628,6 @@ static struct omap_hwmod omap54xx_kbd_hwmod = {
 };
 
 /*
- * 'mailbox' class
- * mailbox module allowing communication between the on-chip processors using a
- * queued mailbox-interrupt mechanism.
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_mailbox_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap54xx_mailbox_hwmod_class = {
-       .name   = "mailbox",
-       .sysc   = &omap54xx_mailbox_sysc,
-};
-
-/* mailbox */
-static struct omap_hwmod omap54xx_mailbox_hwmod = {
-       .name           = "mailbox",
-       .class          = &omap54xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4CFG_MAILBOX_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
- * 'mcbsp' class
- * multi channel buffered serial port controller
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = {
-       .rev_offs       = -ENODEV,
-       .sysc_offs      = 0x008c,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap54xx_mcbsp_hwmod_class = {
-       .name   = "mcbsp",
-       .sysc   = &omap54xx_mcbsp_sysc,
-};
-
-/* mcbsp1 */
-static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = {
-       { .role = "pad_fck", .clk = "pad_clks_ck" },
-       { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" },
-};
-
-static struct omap_hwmod omap54xx_mcbsp1_hwmod = {
-       .name           = "mcbsp1",
-       .class          = &omap54xx_mcbsp_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "mcbsp1_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_MCBSP1_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = mcbsp1_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(mcbsp1_opt_clks),
-};
-
-/* mcbsp2 */
-static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = {
-       { .role = "pad_fck", .clk = "pad_clks_ck" },
-       { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" },
-};
-
-static struct omap_hwmod omap54xx_mcbsp2_hwmod = {
-       .name           = "mcbsp2",
-       .class          = &omap54xx_mcbsp_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "mcbsp2_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_MCBSP2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = mcbsp2_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(mcbsp2_opt_clks),
-};
-
-/* mcbsp3 */
-static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = {
-       { .role = "pad_fck", .clk = "pad_clks_ck" },
-       { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" },
-};
-
-static struct omap_hwmod omap54xx_mcbsp3_hwmod = {
-       .name           = "mcbsp3",
-       .class          = &omap54xx_mcbsp_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "mcbsp3_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_MCBSP3_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = mcbsp3_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(mcbsp3_opt_clks),
-};
-
-/*
  * 'mcpdm' class
  * multi channel pdm controller (proprietary interface with phoenix power
  * ic)
@@ -795,86 +676,6 @@ static struct omap_hwmod omap54xx_mcpdm_hwmod = {
        },
 };
 
-/*
- * 'mcspi' class
- * multichannel serial port interface (mcspi) / master/slave synchronous serial
- * bus
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_mcspi_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap54xx_mcspi_hwmod_class = {
-       .name   = "mcspi",
-       .sysc   = &omap54xx_mcspi_sysc,
-};
-
-/* mcspi1 */
-static struct omap_hwmod omap54xx_mcspi1_hwmod = {
-       .name           = "mcspi1",
-       .class          = &omap54xx_mcspi_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "func_48m_fclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* mcspi2 */
-static struct omap_hwmod omap54xx_mcspi2_hwmod = {
-       .name           = "mcspi2",
-       .class          = &omap54xx_mcspi_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "func_48m_fclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* mcspi3 */
-static struct omap_hwmod omap54xx_mcspi3_hwmod = {
-       .name           = "mcspi3",
-       .class          = &omap54xx_mcspi_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "func_48m_fclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* mcspi4 */
-static struct omap_hwmod omap54xx_mcspi4_hwmod = {
-       .name           = "mcspi4",
-       .class          = &omap54xx_mcspi_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "func_48m_fclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /*
  * 'mmu' class
@@ -1392,43 +1193,6 @@ static struct omap_hwmod omap54xx_usb_otg_ss_hwmod = {
        .opt_clks_cnt   = ARRAY_SIZE(usb_otg_ss_opt_clks),
 };
 
-/*
- * 'wd_timer' class
- * 32-bit watchdog upward counter that generates a pulse on the reset pin on
- * overflow condition
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_wd_timer_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap54xx_wd_timer_hwmod_class = {
-       .name           = "wd_timer",
-       .sysc           = &omap54xx_wd_timer_sysc,
-       .pre_shutdown   = &omap2_wd_timer_disable,
-};
-
-/* wd_timer2 */
-static struct omap_hwmod omap54xx_wd_timer2_hwmod = {
-       .name           = "wd_timer2",
-       .class          = &omap54xx_wd_timer_hwmod_class,
-       .clkdm_name     = "wkupaon_clkdm",
-       .main_clk       = "sys_32k_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /*
  * 'ocp2scp' class
@@ -1747,38 +1511,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_wkup__kbd = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> mailbox */
-static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mailbox = {
-       .master         = &omap54xx_l4_cfg_hwmod,
-       .slave          = &omap54xx_mailbox_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> mcbsp1 */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp1 = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_mcbsp1_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> mcbsp2 */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp2 = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_mcbsp2_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> mcbsp3 */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp3 = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_mcbsp3_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4_abe -> mcpdm */
 static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcpdm = {
        .master         = &omap54xx_l4_abe_hwmod,
@@ -1787,38 +1519,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcpdm = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4_per -> mcspi1 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi1 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_mcspi1_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> mcspi2 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi2 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_mcspi2_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> mcspi3 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi3 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_mcspi3_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> mcspi4 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi4 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_mcspi4_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_cfg -> mpu */
 static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = {
        .master         = &omap54xx_l4_cfg_hwmod,
@@ -1955,14 +1655,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_wkup -> wd_timer2 */
-static struct omap_hwmod_ocp_if omap54xx_l4_wkup__wd_timer2 = {
-       .master         = &omap54xx_l4_wkup_hwmod,
-       .slave          = &omap54xx_wd_timer2_hwmod,
-       .clk            = "wkupaon_iclk_mux",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l3_main_1__dmm,
        &omap54xx_l3_main_3__l3_instr,
@@ -1994,15 +1686,7 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_mpu__emif2,
        &omap54xx_l3_main_2__mmu_ipu,
        &omap54xx_l4_wkup__kbd,
-       &omap54xx_l4_cfg__mailbox,
-       &omap54xx_l4_abe__mcbsp1,
-       &omap54xx_l4_abe__mcbsp2,
-       &omap54xx_l4_abe__mcbsp3,
        &omap54xx_l4_abe__mcpdm,
-       &omap54xx_l4_per__mcspi1,
-       &omap54xx_l4_per__mcspi2,
-       &omap54xx_l4_per__mcspi3,
-       &omap54xx_l4_per__mcspi4,
        &omap54xx_l4_cfg__mpu,
        &omap54xx_l4_cfg__spinlock,
        &omap54xx_l4_cfg__ocp2scp1,
@@ -2020,7 +1704,6 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l4_cfg__usb_host_hs,
        &omap54xx_l4_cfg__usb_tll_hs,
        &omap54xx_l4_cfg__usb_otg_ss,
-       &omap54xx_l4_wkup__wd_timer2,
        &omap54xx_l4_cfg__ocp2scp3,
        &omap54xx_l4_cfg__sata,
        NULL,
index e5bd549..f8715bd 100644 (file)
@@ -24,7 +24,6 @@
 #include "cm1_7xx.h"
 #include "cm2_7xx.h"
 #include "prm7xx.h"
-#include "wd_timer.h"
 #include "soc.h"
 
 /* Base offset for all DRA7XX interrupts external to MPUSS */
@@ -683,7 +682,7 @@ static struct omap_hwmod_class dra7xx_sha0_hwmod_class = {
        .sysc           = &dra7xx_sha0_sysc,
 };
 
-struct omap_hwmod dra7xx_sha0_hwmod = {
+static struct omap_hwmod dra7xx_sha0_hwmod = {
        .name           = "sham",
        .class          = &dra7xx_sha0_hwmod_class,
        .clkdm_name     = "l4sec_clkdm",
@@ -772,229 +771,7 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = {
        },
 };
 
-/*
- * 'hdq1w' class
- *
- */
-
-static struct omap_hwmod_class_sysconfig dra7xx_hdq1w_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0014,
-       .syss_offs      = 0x0018,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
 
-static struct omap_hwmod_class dra7xx_hdq1w_hwmod_class = {
-       .name   = "hdq1w",
-       .sysc   = &dra7xx_hdq1w_sysc,
-};
-
-/* hdq1w */
-
-static struct omap_hwmod dra7xx_hdq1w_hwmod = {
-       .name           = "hdq1w",
-       .class          = &dra7xx_hdq1w_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .flags          = HWMOD_INIT_NO_RESET,
-       .main_clk       = "func_12m_fclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'mailbox' class
- *
- */
-
-static struct omap_hwmod_class_sysconfig dra7xx_mailbox_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class dra7xx_mailbox_hwmod_class = {
-       .name   = "mailbox",
-       .sysc   = &dra7xx_mailbox_sysc,
-};
-
-/* mailbox1 */
-static struct omap_hwmod dra7xx_mailbox1_hwmod = {
-       .name           = "mailbox1",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX1_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX1_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox2 */
-static struct omap_hwmod dra7xx_mailbox2_hwmod = {
-       .name           = "mailbox2",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX2_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX2_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox3 */
-static struct omap_hwmod dra7xx_mailbox3_hwmod = {
-       .name           = "mailbox3",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX3_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX3_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox4 */
-static struct omap_hwmod dra7xx_mailbox4_hwmod = {
-       .name           = "mailbox4",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX4_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX4_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox5 */
-static struct omap_hwmod dra7xx_mailbox5_hwmod = {
-       .name           = "mailbox5",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX5_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX5_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox6 */
-static struct omap_hwmod dra7xx_mailbox6_hwmod = {
-       .name           = "mailbox6",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX6_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX6_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox7 */
-static struct omap_hwmod dra7xx_mailbox7_hwmod = {
-       .name           = "mailbox7",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX7_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX7_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox8 */
-static struct omap_hwmod dra7xx_mailbox8_hwmod = {
-       .name           = "mailbox8",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX8_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX8_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox9 */
-static struct omap_hwmod dra7xx_mailbox9_hwmod = {
-       .name           = "mailbox9",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX9_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX9_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox10 */
-static struct omap_hwmod dra7xx_mailbox10_hwmod = {
-       .name           = "mailbox10",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX10_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX10_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox11 */
-static struct omap_hwmod dra7xx_mailbox11_hwmod = {
-       .name           = "mailbox11",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX11_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX11_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox12 */
-static struct omap_hwmod dra7xx_mailbox12_hwmod = {
-       .name           = "mailbox12",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX12_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX12_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* mailbox13 */
-static struct omap_hwmod dra7xx_mailbox13_hwmod = {
-       .name           = "mailbox13",
-       .class          = &dra7xx_mailbox_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX13_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_MAILBOX13_CONTEXT_OFFSET,
-               },
-       },
-};
 
 /*
  * 'mpu' class
@@ -1655,34 +1432,6 @@ static struct omap_hwmod dra7xx_des_hwmod = {
        },
 };
 
-/* rng */
-static struct omap_hwmod_class_sysconfig dra7xx_rng_sysc = {
-       .rev_offs       = 0x1fe0,
-       .sysc_offs      = 0x1fe4,
-       .sysc_flags     = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE,
-       .idlemodes      = SIDLE_FORCE | SIDLE_NO,
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class dra7xx_rng_hwmod_class = {
-       .name           = "rng",
-       .sysc           = &dra7xx_rng_sysc,
-};
-
-static struct omap_hwmod dra7xx_rng_hwmod = {
-       .name           = "rng",
-       .class          = &dra7xx_rng_hwmod_class,
-       .flags          = HWMOD_SWSUP_SIDLE,
-       .clkdm_name     = "l4sec_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4SEC_RNG_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4SEC_RNG_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
 /*
  * 'usb_otg_ss' class
  *
@@ -1815,43 +1564,6 @@ static struct omap_hwmod dra7xx_vcp2_hwmod = {
        },
 };
 
-/*
- * 'wd_timer' class
- *
- */
-
-static struct omap_hwmod_class_sysconfig dra7xx_wd_timer_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class dra7xx_wd_timer_hwmod_class = {
-       .name           = "wd_timer",
-       .sysc           = &dra7xx_wd_timer_sysc,
-       .pre_shutdown   = &omap2_wd_timer_disable,
-       .reset          = &omap2_wd_timer_reset,
-};
-
-/* wd_timer2 */
-static struct omap_hwmod dra7xx_wd_timer2_hwmod = {
-       .name           = "wd_timer2",
-       .class          = &dra7xx_wd_timer_hwmod_class,
-       .clkdm_name     = "wkupaon_clkdm",
-       .main_clk       = "sys_32k_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 
 /*
@@ -2090,118 +1802,6 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__gpmc = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_per1 -> hdq1w */
-static struct omap_hwmod_ocp_if dra7xx_l4_per1__hdq1w = {
-       .master         = &dra7xx_l4_per1_hwmod,
-       .slave          = &dra7xx_hdq1w_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> mailbox1 */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mailbox1 = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_mailbox1_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox2 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox2 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox2_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox3 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox3 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox3_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox4 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox4 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox4_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox5 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox5 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox5_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox6 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox6 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox6_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox7 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox7 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox7_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox8 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox8 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox8_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox9 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox9 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox9_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox10 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox10 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox10_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox11 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox11 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox11_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox12 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox12 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox12_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> mailbox13 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox13 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_mailbox13_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_cfg -> mpu */
 static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mpu = {
        .master         = &dra7xx_l4_cfg_hwmod,
@@ -2442,13 +2042,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__des = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_per1 -> rng */
-static struct omap_hwmod_ocp_if dra7xx_l4_per1__rng = {
-       .master         = &dra7xx_l4_per1_hwmod,
-       .slave          = &dra7xx_rng_hwmod,
-       .user           = OCP_USER_MPU,
-};
-
 /* l4_per3 -> usb_otg_ss1 */
 static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = {
        .master         = &dra7xx_l4_per3_hwmod,
@@ -2513,14 +2106,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per2__vcp2 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_wkup -> wd_timer2 */
-static struct omap_hwmod_ocp_if dra7xx_l4_wkup__wd_timer2 = {
-       .master         = &dra7xx_l4_wkup_hwmod,
-       .slave          = &dra7xx_wd_timer2_hwmod,
-       .clk            = "wkupaon_iclk_mux",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_per2 -> epwmss0 */
 static struct omap_hwmod_ocp_if dra7xx_l4_per2__epwmss0 = {
        .master         = &dra7xx_l4_per2_hwmod,
@@ -2575,20 +2160,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
        &dra7xx_l3_main_1__sha0,
        &dra7xx_l4_per1__elm,
        &dra7xx_l3_main_1__gpmc,
-       &dra7xx_l4_per1__hdq1w,
-       &dra7xx_l4_cfg__mailbox1,
-       &dra7xx_l4_per3__mailbox2,
-       &dra7xx_l4_per3__mailbox3,
-       &dra7xx_l4_per3__mailbox4,
-       &dra7xx_l4_per3__mailbox5,
-       &dra7xx_l4_per3__mailbox6,
-       &dra7xx_l4_per3__mailbox7,
-       &dra7xx_l4_per3__mailbox8,
-       &dra7xx_l4_per3__mailbox9,
-       &dra7xx_l4_per3__mailbox10,
-       &dra7xx_l4_per3__mailbox11,
-       &dra7xx_l4_per3__mailbox12,
-       &dra7xx_l4_per3__mailbox13,
        &dra7xx_l4_cfg__mpu,
        &dra7xx_l4_cfg__ocp2scp1,
        &dra7xx_l4_cfg__ocp2scp3,
@@ -2624,7 +2195,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
        &dra7xx_l4_per2__vcp1,
        &dra7xx_l3_main_1__vcp2,
        &dra7xx_l4_per2__vcp2,
-       &dra7xx_l4_wkup__wd_timer2,
        &dra7xx_l4_per2__epwmss0,
        &dra7xx_l4_per2__epwmss1,
        &dra7xx_l4_per2__epwmss2,
@@ -2634,7 +2204,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
 /* GP-only hwmod links */
 static struct omap_hwmod_ocp_if *dra7xx_gp_hwmod_ocp_ifs[] __initdata = {
        &dra7xx_l4_wkup__timer12,
-       &dra7xx_l4_per1__rng,
        NULL,
 };
 
index 6787f1e..a642d3b 100644 (file)
 #define OMAP4_VDD_CORE_SR_VOLT_REG     0x61
 #define OMAP4_VDD_CORE_SR_CMD_REG      0x62
 
-#define OMAP4_VP_CONFIG_ERROROFFSET    0x00
-#define OMAP4_VP_VSTEPMIN_VSTEPMIN     0x01
-#define OMAP4_VP_VSTEPMAX_VSTEPMAX     0x04
-#define OMAP4_VP_VLIMITTO_TIMEOUT_US   200
-
 static bool is_offset_valid;
 static u8 smps_offset;
 
@@ -219,7 +214,8 @@ int __init omap4_twl_init(void)
 {
        struct voltagedomain *voltdm;
 
-       if (!cpu_is_omap44xx())
+       if (!cpu_is_omap44xx() ||
+           of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
                return -ENODEV;
 
        voltdm = voltdm_lookup("mpu");
index adea43e..985aeab 100644 (file)
 
 #define OMAP4430_VDD_MPU_OPP50_UV              1025000
 #define OMAP4430_VDD_MPU_OPP100_UV             1200000
-#define OMAP4430_VDD_MPU_OPPTURBO_UV           1313000
-#define OMAP4430_VDD_MPU_OPPNITRO_UV           1375000
+#define OMAP4430_VDD_MPU_OPPTURBO_UV           1325000
+#define OMAP4430_VDD_MPU_OPPNITRO_UV           1388000
+#define OMAP4430_VDD_MPU_OPPNITROSB_UV         1398000
 
 struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
        VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
        VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
        VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
        VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+       VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITROSB_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITROSB, 0xfa, 0x27),
        VOLT_DATA_DEFINE(0, 0, 0, 0),
 };
 
-#define OMAP4430_VDD_IVA_OPP50_UV              1013000
-#define OMAP4430_VDD_IVA_OPP100_UV             1188000
-#define OMAP4430_VDD_IVA_OPPTURBO_UV           1300000
+#define OMAP4430_VDD_IVA_OPP50_UV               950000
+#define OMAP4430_VDD_IVA_OPP100_UV             1114000
+#define OMAP4430_VDD_IVA_OPPTURBO_UV           1291000
 
 struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
        VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
@@ -54,8 +56,8 @@ struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
        VOLT_DATA_DEFINE(0, 0, 0, 0),
 };
 
-#define OMAP4430_VDD_CORE_OPP50_UV             1025000
-#define OMAP4430_VDD_CORE_OPP100_UV            1200000
+#define OMAP4430_VDD_CORE_OPP50_UV              962000
+#define OMAP4430_VDD_CORE_OPP100_UV            1127000
 
 struct omap_volt_data omap443x_vdd_core_volt_data[] = {
        VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
index c47a2af..ca52271 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
-#include <linux/ti_wilink_st.h>
 #include <linux/wl12xx.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -144,53 +143,6 @@ static void __init omap3_sbc_t3530_legacy_init(void)
        omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
 }
 
-static struct ti_st_plat_data wilink_pdata = {
-       .nshutdown_gpio = 137,
-       .dev_name = "/dev/ttyO1",
-       .flow_cntrl = 1,
-       .baud_rate = 300000,
-};
-
-static struct platform_device wl18xx_device = {
-       .name   = "kim",
-       .id     = -1,
-       .dev    = {
-               .platform_data = &wilink_pdata,
-       }
-};
-
-static struct ti_st_plat_data wilink7_pdata = {
-       .nshutdown_gpio = 162,
-       .dev_name = "/dev/ttyO1",
-       .flow_cntrl = 1,
-       .baud_rate = 3000000,
-};
-
-static struct platform_device wl128x_device = {
-       .name   = "kim",
-       .id     = -1,
-       .dev    = {
-               .platform_data = &wilink7_pdata,
-       }
-};
-
-static struct platform_device btwilink_device = {
-       .name   = "btwilink",
-       .id     = -1,
-};
-
-static void __init omap3_igep0020_rev_f_legacy_init(void)
-{
-       platform_device_register(&wl18xx_device);
-       platform_device_register(&btwilink_device);
-}
-
-static void __init omap3_igep0030_rev_g_legacy_init(void)
-{
-       platform_device_register(&wl18xx_device);
-       platform_device_register(&btwilink_device);
-}
-
 static void __init omap3_evm_legacy_init(void)
 {
        hsmmc2_internal_input_clk();
@@ -293,8 +245,6 @@ static void __init omap3_tao3530_legacy_init(void)
 static void __init omap3_logicpd_torpedo_init(void)
 {
        omap3_gpio126_127_129();
-       platform_device_register(&wl128x_device);
-       platform_device_register(&btwilink_device);
 }
 
 /* omap3pandora legacy devices */
@@ -575,8 +525,6 @@ static struct pdata_init pdata_quirks[] __initdata = {
        { "nokia,omap3-n900", nokia_n900_legacy_init, },
        { "nokia,omap3-n9", hsmmc2_internal_input_clk, },
        { "nokia,omap3-n950", hsmmc2_internal_input_clk, },
-       { "isee,omap3-igep0020-rev-f", omap3_igep0020_rev_f_legacy_init, },
-       { "isee,omap3-igep0030-rev-g", omap3_igep0030_rev_g_legacy_init, },
        { "logicpd,dm3730-torpedo-devkit", omap3_logicpd_torpedo_init, },
        { "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
        { "ti,am3517-evm", am3517_evm_legacy_init, },
index 7ac9af5..01ec1ba 100644 (file)
@@ -148,6 +148,7 @@ int __init omap2_common_pm_late_init(void)
        /* Init the voltage layer */
        omap3_twl_init();
        omap4_twl_init();
+       omap4_cpcap_init();
        omap_voltage_late_init();
 
        /* Smartreflex device init */
index 8a55b69..2a883a0 100644 (file)
@@ -107,6 +107,11 @@ extern u16 pm44xx_errata;
 #define IS_PM44XX_ERRATUM(id)          0
 #endif
 
+#define OMAP4_VP_CONFIG_ERROROFFSET    0x00
+#define OMAP4_VP_VSTEPMIN_VSTEPMIN     0x01
+#define OMAP4_VP_VSTEPMAX_VSTEPMAX     0x04
+#define OMAP4_VP_VLIMITTO_TIMEOUT_US   200
+
 #ifdef CONFIG_POWER_AVS_OMAP
 extern int omap_devinit_smartreflex(void);
 extern void omap_enable_smartreflex_on_init(void);
@@ -134,6 +139,15 @@ static inline int omap4_twl_init(void)
 }
 #endif
 
+#if IS_ENABLED(CONFIG_MFD_CPCAP)
+extern int omap4_cpcap_init(void);
+#else
+static inline int omap4_cpcap_init(void)
+{
+       return -EINVAL;
+}
+#endif
+
 #ifdef CONFIG_PM
 extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
 extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
index 485550a..5a7a949 100644 (file)
@@ -128,18 +128,9 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
                return 0;
        }
 
-       /*
-        * Bootloader or kexec boot may have LOGICRETSTATE cleared
-        * for some domains. This is the case when kexec booting from
-        * Android kernels that support off mode for example.
-        * Make sure it's set at least for core and per, otherwise
-        * we currently will see lost GPIO interrupts for wlcore and
-        * smsc911x at least if per hits retention during idle.
-        */
        if (!strncmp(pwrdm->name, "core", 4) ||
-           !strncmp(pwrdm->name, "l4per", 5) ||
-           !strncmp(pwrdm->name, "wkup", 4))
-               pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_RET);
+           !strncmp(pwrdm->name, "l4per", 5))
+               pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_OFF);
 
        pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
        if (!pwrst)
diff --git a/arch/arm/mach-omap2/pmic-cpcap.c b/arch/arm/mach-omap2/pmic-cpcap.c
new file mode 100644 (file)
index 0000000..eab281a
--- /dev/null
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * pmic-cpcap.c - CPCAP-specific functions for the OPP code
+ *
+ * Adapted from Motorola Mapphone Android Linux kernel
+ * Copyright (C) 2011 Motorola, Inc.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include "soc.h"
+#include "pm.h"
+#include "voltage.h"
+
+#include <linux/init.h>
+#include "vc.h"
+
+/**
+ * omap_cpcap_vsel_to_vdc - convert CPCAP VSEL value to microvolts DC
+ * @vsel: CPCAP VSEL value to convert
+ *
+ * Returns the microvolts DC that the CPCAP PMIC should generate when
+ * programmed with @vsel.
+ */
+static unsigned long omap_cpcap_vsel_to_uv(unsigned char vsel)
+{
+       if (vsel > 0x44)
+               vsel = 0x44;
+       return (((vsel * 125) + 6000)) * 100;
+}
+
+/**
+ * omap_cpcap_uv_to_vsel - convert microvolts DC to CPCAP VSEL value
+ * @uv: microvolts DC to convert
+ *
+ * Returns the VSEL value necessary for the CPCAP PMIC to
+ * generate an output voltage equal to or greater than @uv microvolts DC.
+ */
+static unsigned char omap_cpcap_uv_to_vsel(unsigned long uv)
+{
+       if (uv < 600000)
+               uv = 600000;
+       else if (uv > 1450000)
+               uv = 1450000;
+       return DIV_ROUND_UP(uv - 600000, 12500);
+}
+
+static struct omap_voltdm_pmic omap_cpcap_core = {
+       .slew_rate = 4000,
+       .step_size = 12500,
+       .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+       .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+       .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+       .vddmin = 900000,
+       .vddmax = 1350000,
+       .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+       .i2c_slave_addr = 0x02,
+       .volt_reg_addr = 0x00,
+       .cmd_reg_addr = 0x01,
+       .i2c_high_speed = false,
+       .vsel_to_uv = omap_cpcap_vsel_to_uv,
+       .uv_to_vsel = omap_cpcap_uv_to_vsel,
+};
+
+static struct omap_voltdm_pmic omap_cpcap_iva = {
+       .slew_rate = 4000,
+       .step_size = 12500,
+       .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+       .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+       .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+       .vddmin = 900000,
+       .vddmax = 1350000,
+       .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+       .i2c_slave_addr = 0x44,
+       .volt_reg_addr = 0x0,
+       .cmd_reg_addr = 0x01,
+       .i2c_high_speed = false,
+       .vsel_to_uv = omap_cpcap_vsel_to_uv,
+       .uv_to_vsel = omap_cpcap_uv_to_vsel,
+};
+
+/**
+ * omap_max8952_vsel_to_vdc - convert MAX8952 VSEL value to microvolts DC
+ * @vsel: MAX8952 VSEL value to convert
+ *
+ * Returns the microvolts DC that the MAX8952 Regulator should generate when
+ * programmed with @vsel.
+ */
+static unsigned long omap_max8952_vsel_to_uv(unsigned char vsel)
+{
+       if (vsel > 0x3F)
+               vsel = 0x3F;
+       return (((vsel * 100) + 7700)) * 100;
+}
+
+/**
+ * omap_max8952_uv_to_vsel - convert microvolts DC to MAX8952 VSEL value
+ * @uv: microvolts DC to convert
+ *
+ * Returns the VSEL value necessary for the MAX8952 Regulator to
+ * generate an output voltage equal to or greater than @uv microvolts DC.
+ */
+static unsigned char omap_max8952_uv_to_vsel(unsigned long uv)
+{
+       if (uv < 770000)
+               uv = 770000;
+       else if (uv > 1400000)
+               uv = 1400000;
+       return DIV_ROUND_UP(uv - 770000, 10000);
+}
+
+static struct omap_voltdm_pmic omap443x_max8952_mpu = {
+       .slew_rate = 16000,
+       .step_size = 10000,
+       .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+       .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+       .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+       .vddmin = 900000,
+       .vddmax = 1400000,
+       .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+       .i2c_slave_addr = 0x60,
+       .volt_reg_addr = 0x03,
+       .cmd_reg_addr = 0x03,
+       .i2c_high_speed = false,
+       .vsel_to_uv = omap_max8952_vsel_to_uv,
+       .uv_to_vsel = omap_max8952_uv_to_vsel,
+};
+
+/**
+ * omap_fan5355_vsel_to_vdc - convert FAN535503 VSEL value to microvolts DC
+ * @vsel: FAN535503 VSEL value to convert
+ *
+ * Returns the microvolts DC that the FAN535503 Regulator should generate when
+ * programmed with @vsel.
+ */
+static unsigned long omap_fan535503_vsel_to_uv(unsigned char vsel)
+{
+       /* Extract bits[5:0] */
+       vsel &= 0x3F;
+
+       return (((vsel * 125) + 7500)) * 100;
+}
+
+/**
+ * omap_fan535508_vsel_to_vdc - convert FAN535508 VSEL value to microvolts DC
+ * @vsel: FAN535508 VSEL value to convert
+ *
+ * Returns the microvolts DC that the FAN535508 Regulator should generate when
+ * programmed with @vsel.
+ */
+static unsigned long omap_fan535508_vsel_to_uv(unsigned char vsel)
+{
+       /* Extract bits[5:0] */
+       vsel &= 0x3F;
+
+       if (vsel > 0x37)
+               vsel = 0x37;
+       return (((vsel * 125) + 7500)) * 100;
+}
+
+
+/**
+ * omap_fan535503_uv_to_vsel - convert microvolts DC to FAN535503 VSEL value
+ * @uv: microvolts DC to convert
+ *
+ * Returns the VSEL value necessary for the MAX8952 Regulator to
+ * generate an output voltage equal to or greater than @uv microvolts DC.
+ */
+static unsigned char omap_fan535503_uv_to_vsel(unsigned long uv)
+{
+       unsigned char vsel;
+       if (uv < 750000)
+               uv = 750000;
+       else if (uv > 1537500)
+               uv = 1537500;
+
+       vsel = DIV_ROUND_UP(uv - 750000, 12500);
+       return vsel | 0xC0;
+}
+
+/**
+ * omap_fan535508_uv_to_vsel - convert microvolts DC to FAN535508 VSEL value
+ * @uv: microvolts DC to convert
+ *
+ * Returns the VSEL value necessary for the MAX8952 Regulator to
+ * generate an output voltage equal to or greater than @uv microvolts DC.
+ */
+static unsigned char omap_fan535508_uv_to_vsel(unsigned long uv)
+{
+       unsigned char vsel;
+       if (uv < 750000)
+               uv = 750000;
+       else if (uv > 1437500)
+               uv = 1437500;
+
+       vsel = DIV_ROUND_UP(uv - 750000, 12500);
+       return vsel | 0xC0;
+}
+
+/* fan5335-core */
+static struct omap_voltdm_pmic omap4_fan_core = {
+       .slew_rate = 4000,
+       .step_size = 12500,
+       .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+       .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+       .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+       .vddmin = 850000,
+       .vddmax = 1375000,
+       .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+       .i2c_slave_addr = 0x4A,
+       .i2c_high_speed = false,
+       .volt_reg_addr = 0x01,
+       .cmd_reg_addr = 0x01,
+       .vsel_to_uv = omap_fan535508_vsel_to_uv,
+       .uv_to_vsel = omap_fan535508_uv_to_vsel,
+};
+
+/* fan5335 iva */
+static struct omap_voltdm_pmic omap4_fan_iva = {
+       .slew_rate = 4000,
+       .step_size = 12500,
+       .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+       .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+       .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+       .vddmin = 850000,
+       .vddmax = 1375000,
+       .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+       .i2c_slave_addr = 0x48,
+       .volt_reg_addr = 0x01,
+       .cmd_reg_addr = 0x01,
+       .i2c_high_speed = false,
+       .vsel_to_uv = omap_fan535503_vsel_to_uv,
+       .uv_to_vsel = omap_fan535503_uv_to_vsel,
+};
+
+int __init omap4_cpcap_init(void)
+{
+       struct voltagedomain *voltdm;
+
+       if (!of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
+               return -ENODEV;
+
+       voltdm = voltdm_lookup("mpu");
+       omap_voltage_register_pmic(voltdm, &omap443x_max8952_mpu);
+
+       if (of_machine_is_compatible("motorola,droid-bionic")) {
+               voltdm = voltdm_lookup("mpu");
+               omap_voltage_register_pmic(voltdm, &omap_cpcap_core);
+
+               voltdm = voltdm_lookup("mpu");
+               omap_voltage_register_pmic(voltdm, &omap_cpcap_iva);
+       } else {
+               voltdm = voltdm_lookup("core");
+               omap_voltage_register_pmic(voltdm, &omap4_fan_core);
+
+               voltdm = voltdm_lookup("iva");
+               omap_voltage_register_pmic(voltdm, &omap4_fan_iva);
+       }
+
+       return 0;
+}
+
+static int __init cpcap_late_init(void)
+{
+       omap4_vc_set_pmic_signaling(PWRDM_POWER_RET);
+
+       return 0;
+}
+omap_late_initcall(cpcap_late_init);
index 1d9346f..25093c1 100644 (file)
@@ -745,7 +745,7 @@ struct pwrdm_ops omap4_pwrdm_operations = {
 
 static int omap44xx_prm_late_init(void);
 
-void prm_save_context(void)
+static void prm_save_context(void)
 {
        omap_prm_context.irq_enable =
                        omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
@@ -756,7 +756,7 @@ void prm_save_context(void)
                                                omap4_prcm_irq_setup.pm_ctrl);
 }
 
-void prm_restore_context(void)
+static void prm_restore_context(void)
 {
        omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
                                 OMAP4430_PRM_OCP_SOCKET_INST,
index 07bea84..0d0a731 100644 (file)
@@ -545,7 +545,7 @@ static void __init __omap_sync32k_timer_init(int clkev_nr, const char *clkev_src
        omap2_gp_clockevent_init(clkev_nr, clkev_src, clkev_prop);
 
        /* Enable the use of clocksource="gp_timer" kernel parameter */
-       if (use_gptimer_clksrc || gptimer)
+       if (clksrc_nr && (use_gptimer_clksrc || gptimer))
                omap2_gptimer_clocksource_init(clksrc_nr, clksrc_src,
                                                clksrc_prop);
        else
@@ -586,7 +586,7 @@ void __init omap3_gptimer_timer_init(void)
 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);
+                                 0, NULL, NULL, false);
 }
 
 void __init omap4_local_timer_init(void)
index d76b1e5..86f1ac4 100644 (file)
 #include "scrm44xx.h"
 #include "control.h"
 
+#define OMAP4430_VDD_IVA_I2C_DISABLE           BIT(14)
+#define OMAP4430_VDD_MPU_I2C_DISABLE           BIT(13)
+#define OMAP4430_VDD_CORE_I2C_DISABLE          BIT(12)
+#define OMAP4430_VDD_IVA_PRESENCE              BIT(9)
+#define OMAP4430_VDD_MPU_PRESENCE              BIT(8)
+#define OMAP4430_AUTO_CTRL_VDD_IVA(x)          ((x) << 4)
+#define OMAP4430_AUTO_CTRL_VDD_MPU(x)          ((x) << 2)
+#define OMAP4430_AUTO_CTRL_VDD_CORE(x)         ((x) << 0)
+#define OMAP4430_AUTO_CTRL_VDD_RET             2
+
+#define OMAP4430_VDD_I2C_DISABLE_MASK  \
+       (OMAP4430_VDD_IVA_I2C_DISABLE | \
+        OMAP4430_VDD_MPU_I2C_DISABLE | \
+        OMAP4430_VDD_CORE_I2C_DISABLE)
+
+#define OMAP4_VDD_DEFAULT_VAL  \
+       (OMAP4430_VDD_I2C_DISABLE_MASK | \
+        OMAP4430_VDD_IVA_PRESENCE | OMAP4430_VDD_MPU_PRESENCE | \
+        OMAP4430_AUTO_CTRL_VDD_IVA(OMAP4430_AUTO_CTRL_VDD_RET) | \
+        OMAP4430_AUTO_CTRL_VDD_MPU(OMAP4430_AUTO_CTRL_VDD_RET) | \
+        OMAP4430_AUTO_CTRL_VDD_CORE(OMAP4430_AUTO_CTRL_VDD_RET))
+
+#define OMAP4_VDD_RET_VAL      \
+       (OMAP4_VDD_DEFAULT_VAL & ~OMAP4430_VDD_I2C_DISABLE_MASK)
+
 /**
  * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
  * @sa: bit for slave address
@@ -280,6 +305,26 @@ void omap3_vc_set_pmic_signaling(int core_next_state)
        }
 }
 
+void omap4_vc_set_pmic_signaling(int core_next_state)
+{
+       struct voltagedomain *vd = vc.vd;
+       u32 val;
+
+       if (!vd)
+               return;
+
+       switch (core_next_state) {
+       case PWRDM_POWER_RET:
+               val = OMAP4_VDD_RET_VAL;
+               break;
+       default:
+               val = OMAP4_VDD_DEFAULT_VAL;
+               break;
+       }
+
+       vd->write(val, OMAP4_PRM_VOLTCTRL_OFFSET);
+}
+
 /*
  * Configure signal polarity for sys_clkreq and sys_off_mode pins
  * as the default values are wrong and can cause the system to hang
@@ -542,9 +587,19 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
        writel_relaxed(val, OMAP4_SCRM_CLKSETUPTIME);
 }
 
+static void __init omap4_vc_init_pmic_signaling(struct voltagedomain *voltdm)
+{
+       if (vc.vd)
+               return;
+
+       vc.vd = voltdm;
+       voltdm->write(OMAP4_VDD_DEFAULT_VAL, OMAP4_PRM_VOLTCTRL_OFFSET);
+}
+
 /* OMAP4 specific voltage init functions */
 static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
 {
+       omap4_vc_init_pmic_signaling(voltdm);
        omap4_set_timings(voltdm, true);
        omap4_set_timings(voltdm, false);
 }
@@ -615,7 +670,7 @@ static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm)
        const struct i2c_init_data *i2c_data;
 
        if (!voltdm->pmic->i2c_high_speed) {
-               pr_warn("%s: only high speed supported!\n", __func__);
+               pr_info("%s: using bootloader low-speed timings\n", __func__);
                return;
        }
 
index 5bf0886..9e861db 100644 (file)
@@ -117,7 +117,7 @@ extern struct omap_vc_param omap4_iva_vc_data;
 extern struct omap_vc_param omap4_core_vc_data;
 
 void omap3_vc_set_pmic_signaling(int core_next_state);
-
+void omap4_vc_set_pmic_signaling(int core_next_state);
 
 void omap_vc_init_channel(struct voltagedomain *voltdm);
 int omap_vc_pre_scale(struct voltagedomain *voltdm,
index 0474a4b..151e26e 100644 (file)
@@ -89,7 +89,7 @@ static struct spi_board_info mcp251x_board_info[] = {
                .max_speed_hz    = 6500000,
                .bus_num         = 3,
                .chip_select     = 1,
-               .platform_data   = &mcp251x_info,
+               .properties      = mcp251x_properties,
                .controller_data = &mcp251x_chip_info2,
                .irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ2)
        },
@@ -98,7 +98,7 @@ static struct spi_board_info mcp251x_board_info[] = {
                .max_speed_hz    = 6500000,
                .bus_num         = 4,
                .chip_select     = 0,
-               .platform_data   = &mcp251x_info,
+               .properties      = mcp251x_properties,
                .controller_data = &mcp251x_chip_info3,
                .irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ3)
        },
@@ -107,7 +107,7 @@ static struct spi_board_info mcp251x_board_info[] = {
                .max_speed_hz    = 6500000,
                .bus_num         = 4,
                .chip_select     = 1,
-               .platform_data   = &mcp251x_info,
+               .properties      = mcp251x_properties,
                .controller_data = &mcp251x_chip_info4,
                .irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ4)
        }
index 1cdb7bd..9514196 100644 (file)
@@ -113,7 +113,7 @@ void __init s3c2416_map_io(void)
        /* initialize device information early */
        s3c2416_default_sdhci0();
        s3c2416_default_sdhci1();
-       s3c64xx_spi_setname("s3c2443-spi");
+       s3c24xx_spi_setname("s3c2443-spi");
 
        iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
 }
index 313e369..4cbeb74 100644 (file)
@@ -91,7 +91,7 @@ void __init s3c2443_map_io(void)
        s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull;
 
        /* initialize device information early */
-       s3c64xx_spi_setname("s3c2443-spi");
+       s3c24xx_spi_setname("s3c2443-spi");
 
        iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
 }
index bb555cc..1048fac 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 /* re-define device name depending on support. */
-static inline void s3c64xx_spi_setname(char *name)
+static inline void s3c24xx_spi_setname(char *name)
 {
 #ifdef CONFIG_S3C64XX_DEV_SPI0
        s3c64xx_device_spi0.name = name;
index 6aaaa1d..d6b0e3b 100644 (file)
@@ -73,7 +73,7 @@ static int s3c_usb_otgphy_exit(struct platform_device *pdev)
        return 0;
 }
 
-int s5p_usb_phy_init(struct platform_device *pdev, int type)
+int s3c_usb_phy_init(struct platform_device *pdev, int type)
 {
        if (type == USB_PHY_TYPE_DEVICE)
                return s3c_usb_otgphy_init(pdev);
@@ -81,7 +81,7 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type)
        return -EINVAL;
 }
 
-int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+int s3c_usb_phy_exit(struct platform_device *pdev, int type)
 {
        if (type == USB_PHY_TYPE_DEVICE)
                return s3c_usb_otgphy_exit(pdev);
index 9e4bc18..2fd3aa6 100644 (file)
@@ -24,7 +24,6 @@
 #include "rcar-gen2.h"
 
 static const struct of_device_id cpg_matches[] __initconst = {
-       { .compatible = "renesas,rcar-gen2-cpg-clocks", },
        { .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" },
        { .compatible = "renesas,r8a7744-cpg-mssr", .data = "extal" },
        { .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" },
index 47ebcc8..9e4cb2f 100644 (file)
@@ -73,10 +73,10 @@ static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
 
        temp = readl(rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
 
-       if (mode == REBOOT_HARD)
-               temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
-       else
+       if (mode == REBOOT_WARM)
                temp |= RSTMGR_CTRL_SWWARMRSTREQ;
+       else
+               temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
        writel(temp, rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
 }
 
@@ -86,10 +86,10 @@ static void socfpga_arria10_restart(enum reboot_mode mode, const char *cmd)
 
        temp = readl(rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL);
 
-       if (mode == REBOOT_HARD)
-               temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
-       else
+       if (mode == REBOOT_WARM)
                temp |= RSTMGR_CTRL_SWWARMRSTREQ;
+       else
+               temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
        writel(temp, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL);
 }
 
index 67b763f..e3f3481 100644 (file)
@@ -44,16 +44,16 @@ ENTRY(tegra_resume)
        cmp     r6, #TEGRA20
        beq     1f                              @ Yes
        /* Clear the flow controller flags for this CPU. */
-       cpu_to_csr_reg r1, r0
+       cpu_to_csr_reg r3, r0
        mov32   r2, TEGRA_FLOW_CTRL_BASE
-       ldr     r1, [r2, r1]
+       ldr     r1, [r2, r3]
        /* Clear event & intr flag */
        orr     r1, r1, \
                #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
        movw    r0, #0x3FFD     @ enable, cluster_switch, immed, bitmaps
                                @ & ext flags for CPU power mgnt
        bic     r1, r1, r0
-       str     r1, [r2]
+       str     r1, [r2, r3]
 1:
 
        mov32   r9, 0xc09
index b408fa5..3341a12 100644 (file)
@@ -682,10 +682,12 @@ tegra30_enter_sleep:
        dsb
        ldr     r0, [r6, r2] /* memory barrier */
 
+       cmp     r10, #TEGRA30
 halted:
        isb
        dsb
-       wfi     /* CPU should be power gated here */
+       wfine   /* CPU should be power gated here */
+       wfeeq
 
        /* !!!FIXME!!! Implement halt failure handler */
        b       halted
index 354e0e7..1da11bd 100644 (file)
@@ -551,8 +551,9 @@ static struct clk *ve_spc_clk_register(struct device *cpu_dev)
 
 static int __init ve_spc_clk_init(void)
 {
-       int cpu;
+       int cpu, cluster;
        struct clk *clk;
+       bool init_opp_table[MAX_CLUSTERS] = { false };
 
        if (!info)
                return 0; /* Continue only if SPC is initialised */
@@ -578,8 +579,17 @@ static int __init ve_spc_clk_init(void)
                        continue;
                }
 
+               cluster = topology_physical_package_id(cpu_dev->id);
+               if (init_opp_table[cluster])
+                       continue;
+
                if (ve_init_opp_table(cpu_dev))
                        pr_warn("failed to initialise cpu%d opp table\n", cpu);
+               else if (dev_pm_opp_set_sharing_cpus(cpu_dev,
+                        topology_core_cpumask(cpu_dev->id)))
+                       pr_warn("failed to mark OPPs shared for cpu%d\n", cpu);
+               else
+                       init_opp_table[cluster] = true;
        }
 
        platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0);
index f112dde..65e4482 100644 (file)
@@ -1044,7 +1044,7 @@ endif
 
 config CACHE_TAUROS2
        bool "Enable the Tauros2 L2 cache controller"
-       depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
+       depends on (CPU_MOHAWK || CPU_PJ4)
        default y
        select OUTER_CACHE
        help
index 1df6eb4..e822af0 100644 (file)
@@ -529,7 +529,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page)
 
 static bool __in_atomic_pool(void *start, size_t size)
 {
-       return addr_in_gen_pool(atomic_pool, (unsigned long)start, size);
+       return gen_pool_has_addr(atomic_pool, (unsigned long)start, size);
 }
 
 static int __free_from_pool(void *start, size_t size)
index 1d1fa06..1602f6d 100644 (file)
@@ -1010,9 +1010,9 @@ void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd)
        npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_usb_hsotg);
 
        if (!npd->phy_init)
-               npd->phy_init = s5p_usb_phy_init;
+               npd->phy_init = s3c_usb_phy_init;
        if (!npd->phy_exit)
-               npd->phy_exit = s5p_usb_phy_exit;
+               npd->phy_exit = s3c_usb_phy_exit;
 }
 #endif /* CONFIG_S3C_DEV_USB_HSOTG */
 
index 94da89e..759d66a 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef __PLAT_SAMSUNG_USB_PHY_H
 #define __PLAT_SAMSUNG_USB_PHY_H __FILE__
 
-extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
-extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+extern int s3c_usb_phy_init(struct platform_device *pdev, int type);
+extern int s3c_usb_phy_exit(struct platform_device *pdev, int type);
 
 #endif /* __PLAT_SAMSUNG_USB_PHY_H */
index 16d7614..b2b504e 100644 (file)
@@ -37,11 +37,12 @@ config ARCH_BCM2835
        select PINCTRL
        select PINCTRL_BCM2835
        select ARM_AMBA
+       select ARM_GIC
        select ARM_TIMER_SP804
        select HAVE_ARM_ARCH_TIMER
        help
-         This enables support for the Broadcom BCM2837 SoC.
-         This SoC is used in the Raspberry Pi 3 device.
+         This enables support for the Broadcom BCM2837 and BCM2711 SoC.
+         These SoCs are used in the Raspberry Pi 3 and 4 devices.
 
 config ARCH_BCM_IPROC
        bool "Broadcom iProc SoC Family"
@@ -188,6 +189,7 @@ config ARCH_QCOM
 
 config ARCH_REALTEK
        bool "Realtek Platforms"
+       select RESET_CONTROLLER
        help
          This enables support for the ARMv8 based Realtek chipsets,
          like the RTD1295.
@@ -212,6 +214,11 @@ config ARCH_ROCKCHIP
          This enables support for the ARMv8 based Rockchip chipsets,
          like the RK3368.
 
+config ARCH_S32
+       bool "NXP S32 SoC Family"
+       help
+         This enables support for the NXP S32 family of processors.
+
 config ARCH_SEATTLE
        bool "AMD Seattle SoC Family"
        help
index 732daaa..59291e0 100644 (file)
@@ -12,6 +12,9 @@
        model = "Bubblegum-96";
 
        aliases {
+               mmc0 = &mmc0;
+               mmc1 = &mmc1;
+               mmc2 = &mmc2;
                serial5 = &uart5;
        };
 
                device_type = "memory";
                reg = <0x0 0x0 0x0 0x80000000>;
        };
+
+       /* Fixed regulator used in the absence of PMIC */
+       vcc_3v1: vcc-3v1 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.1V";
+               regulator-min-microvolt = <3100000>;
+               regulator-max-microvolt = <3100000>;
+               regulator-always-on;
+       };
+
+       /* Fixed regulator used in the absence of PMIC */
+       sd_vcc: sd-vcc {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.1V";
+               regulator-min-microvolt = <3100000>;
+               regulator-max-microvolt = <3100000>;
+               regulator-always-on;
+       };
 };
 
 &i2c0 {
                        bias-pull-up;
                };
        };
+
+       mmc0_default: mmc0_default {
+               pinmux {
+                       groups = "sd0_d0_mfp", "sd0_d1_mfp", "sd0_d2_d3_mfp",
+                                "sd0_cmd_mfp", "sd0_clk_mfp";
+                       function = "sd0";
+               };
+       };
+
+       mmc2_default: mmc2_default {
+               pinmux {
+                       groups = "nand0_d0_ceb3_mfp";
+                       function = "sd2";
+               };
+       };
+};
+
+/* uSD */
+&mmc0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_default>;
+       no-sdio;
+       no-mmc;
+       no-1-8-v;
+       cd-gpios = <&pinctrl 120 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       vmmc-supply = <&sd_vcc>;
+       vqmmc-supply = <&sd_vcc>;
+};
+
+/* eMMC */
+&mmc2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_default>;
+       no-sdio;
+       no-sd;
+       non-removable;
+       bus-width = <8>;
+       vmmc-supply = <&vcc_3v1>;
 };
 
 &timer {
index df3a68a..eb35cf7 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/actions,s900-cmu.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/actions,s900-reset.h>
 
                        dma-requests = <46>;
                        clocks = <&cmu CLK_DMAC>;
                };
+
+               mmc0: mmc@e0330000 {
+                       compatible = "actions,owl-mmc";
+                       reg = <0x0 0xe0330000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cmu CLK_SD0>;
+                       resets = <&cmu RESET_SD0>;
+                       dmas = <&dma 2>;
+                       dma-names = "mmc";
+                       status = "disabled";
+               };
+
+               mmc1: mmc@e0334000 {
+                       compatible = "actions,owl-mmc";
+                       reg = <0x0 0xe0334000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cmu CLK_SD1>;
+                       resets = <&cmu RESET_SD1>;
+                       dmas = <&dma 3>;
+                       dma-names = "mmc";
+                       status = "disabled";
+               };
+
+               mmc2: mmc@e0338000 {
+                       compatible = "actions,owl-mmc";
+                       reg = <0x0 0xe0338000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cmu CLK_SD2>;
+                       resets = <&cmu RESET_SD2>;
+                       dmas = <&dma 4>;
+                       dma-names = "mmc";
+                       status = "disabled";
+               };
+
+               mmc3: mmc@e033c000 {
+                       compatible = "actions,owl-mmc";
+                       reg = <0x0 0xe033c000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cmu CLK_SD3>;
+                       resets = <&cmu RESET_SD3>;
+                       dmas = <&dma 46>;
+                       dma-names = "mmc";
+                       status = "disabled";
+               };
        };
 };
index 04446e4..f54a415 100644 (file)
        };
 };
 
+&codec {
+       status = "okay";
+};
+
+&codec_analog {
+       cpvdd-supply = <&reg_eldo1>;
+       status = "okay";
+};
+
+&dai {
+       status = "okay";
+};
+
 &de {
        status = "okay";
 };
        vcc-hdmi-supply = <&reg_dldo1>;
 };
 
+&sound {
+       status = "okay";
+       simple-audio-card,widgets = "Headphone", "Headphone Jack",
+                                   "Microphone", "Microphone Jack",
+                                   "Microphone", "Onboard Microphone";
+       simple-audio-card,routing =
+                       "Left DAC", "AIF1 Slot 0 Left",
+                       "Right DAC", "AIF1 Slot 0 Right",
+                       "AIF1 Slot 0 Left ADC", "Left ADC",
+                       "AIF1 Slot 0 Right ADC", "Right ADC",
+                       "Headphone Jack", "HP",
+                       "MIC2", "Microphone Jack",
+                       "Onboard Microphone", "MBIAS",
+                       "MIC1", "Onboard Microphone";
+};
+
 &spi0 {
        status = "okay";
 
index 2509920..920103e 100644 (file)
        aliases {
                ethernet0 = &emac;
                serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
        };
 
        chosen {
        status = "okay";
 };
 
+/* On Pi-2 connector */
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "disabled";
+};
+
+/* On Euler connector */
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+       status = "disabled";
+};
+
+/* On Euler connector, RTS/CTS optional */
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart4_pins>;
+       status = "disabled";
+};
+
 &usb_otg {
        dr_mode = "host";
        status = "okay";
index 1069e70..9704151 100644 (file)
        status = "okay";
 };
 
+&de {
+       status = "okay";
+};
+
 &ehci1 {
        status = "okay";
 };
 
 
-/* The ANX6345 eDP-bridge is on i2c0. There is no linux (mainline)
- * driver for this chip at the moment, the bootloader initializes it.
- * However it can be accessed with the i2c-dev driver from user space.
- */
 &i2c0 {
        clock-frequency = <100000>;
        status = "okay";
+
+       anx6345: anx6345@38 {
+               compatible = "analogix,anx6345";
+               reg = <0x38>;
+               reset-gpios = <&pio 3 24 GPIO_ACTIVE_LOW>; /* PD24 */
+               dvdd25-supply = <&reg_dldo2>;
+               dvdd12-supply = <&reg_dldo3>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               anx6345_in: endpoint {
+                                       remote-endpoint = <&tcon0_out_anx6345>;
+                               };
+                       };
+               };
+       };
+};
+
+&mixer0 {
+       status = "okay";
 };
 
 &mmc0 {
        status = "okay";
 };
 
+&tcon0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&lcd_rgb666_pins>;
+
+       status = "okay";
+};
+
+&tcon0_out {
+       tcon0_out_anx6345: endpoint@0 {
+               reg = <0>;
+               remote-endpoint = <&anx6345_in>;
+       };
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pb_pins>;
index 70f4cce..27e4823 100644 (file)
                clock-output-names = "ext-osc32k";
        };
 
+       pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
        psci {
                compatible = "arm,psci-0.2";
                method = "smc";
                        reg = <0x1c14000 0x400>;
                };
 
+               crypto: crypto@1c15000 {
+                       compatible = "allwinner,sun50i-a64-crypto";
+                       reg = <0x01c15000 0x1000>;
+                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>;
+                       clock-names = "bus", "mod";
+                       resets = <&ccu RST_BUS_CE>;
+               };
+
                usb_otg: usb@1c19000 {
                        compatible = "allwinner,sun8i-a33-musb";
                        reg = <0x01c19000 0x0400>;
index 82f4b44..5bec574 100644 (file)
@@ -23,6 +23,8 @@
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 2 7 GPIO_ACTIVE_LOW>; /* PC7 */
                post-power-on-delay-ms = <200>;
+               clocks = <&rtc 1>;
+               clock-names = "ext_clock";
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+       uart-has-rtscts;
        status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               clocks = <&rtc 1>;
+               clock-names = "lpo";
+               vbat-supply = <&reg_vcc3v3>;
+               vddio-supply = <&reg_vcc3v3>;
+               shutdown-gpios = <&pio 2 4 GPIO_ACTIVE_HIGH>; /* PC4 */
+               device-wakeup-gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */
+       };
 };
index f002a49..e92c4de 100644 (file)
                        allwinner,sram = <&ve_sram 1>;
                };
 
+               crypto: crypto@1c15000 {
+                       compatible = "allwinner,sun50i-h5-crypto";
+                       reg = <0x01c15000 0x1000>;
+                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>;
+                       clock-names = "bus", "mod";
+                       resets = <&ccu RST_BUS_CE>;
+               };
+
                mali: gpu@1e80000 {
                        compatible = "allwinner,sun50i-h5-mali", "arm,mali-450";
                        reg = <0x01e80000 0x30000>;
index ce4b067..f335f74 100644 (file)
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&reg_dcdcc>;
+       status = "okay";
+};
+
 &hdmi {
        status = "okay";
 };
                        };
 
                        reg_dcdcc: dcdcc {
+                               regulator-enable-ramp-delay = <32000>;
                                regulator-min-microvolt = <810000>;
                                regulator-max-microvolt = <1080000>;
                                regulator-name = "vdd-gpu";
index eb379cd..4ed3fc2 100644 (file)
@@ -15,6 +15,7 @@
 
        aliases {
                serial0 = &uart0;
+               serial1 = &uart1;
        };
 
        chosen {
        status = "okay";
 };
 
+&dwc3 {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&reg_dcdcc>;
+       status = "okay";
+};
+
 &hdmi {
        status = "okay";
 };
                        };
 
                        reg_dcdcc: dcdcc {
+                               regulator-enable-ramp-delay = <32000>;
                                regulator-min-microvolt = <810000>;
                                regulator-max-microvolt = <1080000>;
                                regulator-name = "vdd-gpu";
        status = "okay";
 };
 
+/* There's the BT part of the AP6256 connected to that UART */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm4345c5";
+               clocks = <&rtc 1>;
+               clock-names = "lpo";
+               device-wakeup-gpios = <&r_pio 1 2 GPIO_ACTIVE_HIGH>; /* PM2 */
+               host-wakeup-gpios = <&r_pio 1 1 GPIO_ACTIVE_HIGH>; /* PM1 */
+               shutdown-gpios = <&r_pio 1 4 GPIO_ACTIVE_HIGH>; /* PM4 */
+               max-speed = <1500000>;
+       };
+};
+
 &usb2otg {
        /*
         * This board doesn't have a controllable VBUS even though it
        usb3_vbus-supply = <&reg_vcc5v>;
        status = "okay";
 };
+
+&usb3phy {
+       status = "okay";
+};
index ec9b6a5..df4cbd7 100644 (file)
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&reg_dcdcc>;
+       status = "okay";
+};
+
 &mmc0 {
        vmmc-supply = <&reg_cldo1>;
        cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
                        };
 
                        reg_dcdcc: dcdcc {
+                               regulator-enable-ramp-delay = <32000>;
                                regulator-min-microvolt = <810000>;
                                regulator-max-microvolt = <1080000>;
                                regulator-name = "vdd-gpu";
index 30102da..74899ed 100644 (file)
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&reg_dcdcc>;
+       status = "okay";
+};
+
 &hdmi {
        status = "okay";
 };
                        };
 
                        reg_dcdcc: dcdcc {
+                               regulator-enable-ramp-delay = <32000>;
                                regulator-min-microvolt = <810000>;
                                regulator-max-microvolt = <1080000>;
                                regulator-name = "vdd-gpu";
index 7e7cb10..bccfe1e 100644 (file)
        status = "okay";
 };
 
+&gpu {
+       status = "okay";
+};
+
 &hdmi {
        status = "okay";
 };
index 0d5ea19..2982408 100644 (file)
                        allwinner,sram = <&ve_sram 1>;
                };
 
+               gpu: gpu@1800000 {
+                       compatible = "allwinner,sun50i-h6-mali",
+                                    "arm,mali-t720";
+                       reg = <0x01800000 0x4000>;
+                       interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "job", "mmu", "gpu";
+                       clocks = <&ccu CLK_GPU>, <&ccu CLK_BUS_GPU>;
+                       clock-names = "core", "bus";
+                       resets = <&ccu RST_BUS_GPU>;
+                       status = "disabled";
+               };
+
+               crypto: crypto@1904000 {
+                       compatible = "allwinner,sun50i-h6-crypto";
+                       reg = <0x01904000 0x1000>;
+                       interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>, <&ccu CLK_MBUS_CE>;
+                       clock-names = "bus", "mod", "ram";
+                       resets = <&ccu RST_BUS_CE>;
+               };
+
                syscon: syscon@3000000 {
                        compatible = "allwinner,sun50i-h6-system-control",
                                     "allwinner,sun50i-a64-system-control";
                                pins = "PH0", "PH1";
                                function = "uart0";
                        };
+
+                       uart1_pins: uart1-pins {
+                               pins = "PG6", "PG7";
+                               function = "uart1";
+                       };
+
+                       uart1_rts_cts_pins: uart1-rts-cts-pins {
+                               pins = "PG8", "PG9";
+                               function = "uart1";
+                       };
                };
 
                gic: interrupt-controller@3021000 {
                        status = "disabled";
                };
 
+               dwc3: dwc3@5200000 {
+                       compatible = "snps,dwc3";
+                       reg = <0x05200000 0x10000>;
+                       interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_XHCI>,
+                                <&ccu CLK_BUS_XHCI>,
+                                <&rtc 0>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       resets = <&ccu RST_BUS_XHCI>;
+                       /*
+                        * The datasheet of the chip doesn't declare the
+                        * peripheral function, and there's no boards known
+                        * to have a USB Type-B port routed to the port.
+                        * In addition, no one has tested the peripheral
+                        * function yet.
+                        * So set the dr_mode to "host" in the DTSI file.
+                        */
+                       dr_mode = "host";
+                       phys = <&usb3phy>;
+                       phy-names = "usb3-phy";
+                       status = "disabled";
+               };
+
+               usb3phy: phy@5210000 {
+                       compatible = "allwinner,sun50i-h6-usb3-phy";
+                       reg = <0x5210000 0x10000>;
+                       clocks = <&ccu CLK_USB_PHY1>;
+                       resets = <&ccu RST_USB_PHY1>;
+                       #phy-cells = <0>;
+                       status = "disabled";
+               };
+
                ehci3: usb@5311000 {
                        compatible = "allwinner,sun50i-h6-ehci", "generic-ehci";
                        reg = <0x05311000 0x100>;
                                      "tcon-tv0";
                        clock-output-names = "tcon-top-tv0";
                        resets = <&ccu RST_BUS_TCON_TOP>;
-                       reset-names = "rst";
                        #clock-cells = <1>;
 
                        ports {
index 66e4ffb..fb11ef0 100644 (file)
 
                        qspi_boot: partition@0 {
                                label = "Boot and fpga data";
-                               reg = <0x0 0x4000000>;
+                               reg = <0x0 0x034B0000>;
                        };
 
                        qspi_rootfs: partition@4000000 {
                                label = "Root Filesystem - JFFS2";
-                               reg = <0x4000000 0x4000000>;
+                               reg = <0x034B0000 0x0EB50000>;
                        };
                };
        };
index 84afecb..6340053 100644 (file)
@@ -6,6 +6,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb
@@ -36,3 +37,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts b/arch/arm64/boot/dts/amlogic/meson-a1-ad401.dts
new file mode 100644 (file)
index 0000000..69c25c6
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-a1.dtsi"
+
+/ {
+       compatible = "amlogic,ad401", "amlogic,a1";
+       model = "Amlogic Meson A1 AD401 Development Board";
+
+       aliases {
+               serial0 = &uart_AO_B;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x8000000>;
+       };
+};
+
+&uart_AO_B {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
new file mode 100644 (file)
index 0000000..7210ad0
--- /dev/null
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "amlogic,a1";
+
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               l2: l2-cache0 {
+                       compatible = "cache";
+               };
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               linux,cma {
+                       compatible = "shared-dma-pool";
+                       reusable;
+                       size = <0x0 0x800000>;
+                       alignment = <0x0 0x400000>;
+                       linux,cma-default;
+               };
+       };
+
+       sm: secure-monitor {
+               compatible = "amlogic,meson-gxbb-sm";
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               apb: bus@fe000000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xfe000000 0x0 0x1000000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x1000000>;
+
+                       uart_AO: serial@1c00 {
+                               compatible = "amlogic,meson-gx-uart",
+                                            "amlogic,meson-ao-uart";
+                               reg = <0x0 0x1c00 0x0 0x18>;
+                               interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>, <&xtal>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+
+                       uart_AO_B: serial@2000 {
+                               compatible = "amlogic,meson-gx-uart",
+                                            "amlogic,meson-ao-uart";
+                               reg = <0x0 0x2000 0x0 0x18>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>, <&xtal>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+               };
+
+               gic: interrupt-controller@ff901000 {
+                       compatible = "arm,gic-400";
+                       reg = <0x0 0xff901000 0x0 0x1000>,
+                             <0x0 0xff902000 0x0 0x2000>,
+                             <0x0 0xff904000 0x0 0x2000>,
+                             <0x0 0xff906000 0x0 0x2000>;
+                       interrupt-controller;
+                       interrupts = <GIC_PPI 9
+                               (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       xtal: xtal-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xtal";
+               #clock-cells = <0>;
+       };
+};
index 82919b1..04803c3 100644 (file)
                #address-cells = <1>;
                #size-cells = <1>;
                read-only;
+               secure-monitor = <&sm>;
        };
 
        psci {
 
                        toddr_a: audio-controller@100 {
                                compatible = "amlogic,axg-toddr";
-                               reg = <0x0 0x100 0x0 0x1c>;
+                               reg = <0x0 0x100 0x0 0x2c>;
                                #sound-dai-cells = <0>;
                                sound-name-prefix = "TODDR_A";
                                interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
 
                        toddr_b: audio-controller@140 {
                                compatible = "amlogic,axg-toddr";
-                               reg = <0x0 0x140 0x0 0x1c>;
+                               reg = <0x0 0x140 0x0 0x2c>;
                                #sound-dai-cells = <0>;
                                sound-name-prefix = "TODDR_B";
                                interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>;
 
                        toddr_c: audio-controller@180 {
                                compatible = "amlogic,axg-toddr";
-                               reg = <0x0 0x180 0x0 0x1c>;
+                               reg = <0x0 0x180 0x0 0x2c>;
                                #sound-dai-cells = <0>;
                                sound-name-prefix = "TODDR_C";
                                interrupts = <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>;
 
                        frddr_a: audio-controller@1c0 {
                                compatible = "amlogic,axg-frddr";
-                               reg = <0x0 0x1c0 0x0 0x1c>;
+                               reg = <0x0 0x1c0 0x0 0x2c>;
                                #sound-dai-cells = <0>;
                                sound-name-prefix = "FRDDR_A";
                                interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
 
                        frddr_b: audio-controller@200 {
                                compatible = "amlogic,axg-frddr";
-                               reg = <0x0 0x200 0x0 0x1c>;
+                               reg = <0x0 0x200 0x0 0x2c>;
                                #sound-dai-cells = <0>;
                                sound-name-prefix = "FRDDR_B";
                                interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
 
                        frddr_c: audio-controller@240 {
                                compatible = "amlogic,axg-frddr";
-                               reg = <0x0 0x240 0x0 0x1c>;
+                               reg = <0x0 0x240 0x0 0x2c>;
                                #sound-dai-cells = <0>;
                                sound-name-prefix = "FRDDR_C";
                                interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
index 7ab7117..7fabc8d 100644 (file)
@@ -5,51 +5,42 @@
 
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clock/axg-audio-clkc.h>
 #include <dt-bindings/clock/g12a-clkc.h>
 #include <dt-bindings/clock/g12a-aoclkc.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
-#include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h>
 #include <dt-bindings/reset/amlogic,meson-g12a-reset.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        interrupt-parent = <&gic>;
        #address-cells = <2>;
        #size-cells = <2>;
 
-       tdmif_a: audio-controller-0 {
-               compatible = "amlogic,axg-tdm-iface";
-               #sound-dai-cells = <0>;
-               sound-name-prefix = "TDM_A";
-               clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
-                        <&clkc_audio AUD_CLKID_MST_A_SCLK>,
-                        <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
-               clock-names = "mclk", "sclk", "lrclk";
-               status = "disabled";
-       };
+       chosen {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
 
-       tdmif_b: audio-controller-1 {
-               compatible = "amlogic,axg-tdm-iface";
-               #sound-dai-cells = <0>;
-               sound-name-prefix = "TDM_B";
-               clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
-                        <&clkc_audio AUD_CLKID_MST_B_SCLK>,
-                        <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
-               clock-names = "mclk", "sclk", "lrclk";
-               status = "disabled";
-       };
+               simplefb_cvbs: framebuffer-cvbs {
+                       compatible = "amlogic,simple-framebuffer",
+                                    "simple-framebuffer";
+                       amlogic,pipeline = "vpu-cvbs";
+                       clocks = <&clkc CLKID_HDMI>,
+                                <&clkc CLKID_HTX_PCLK>,
+                                <&clkc CLKID_VPU_INTR>;
+                       status = "disabled";
+               };
 
-       tdmif_c: audio-controller-2 {
-               compatible = "amlogic,axg-tdm-iface";
-               #sound-dai-cells = <0>;
-               sound-name-prefix = "TDM_C";
-               clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
-                        <&clkc_audio AUD_CLKID_MST_C_SCLK>,
-                        <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
-               clock-names = "mclk", "sclk", "lrclk";
-               status = "disabled";
+               simplefb_hdmi: framebuffer-hdmi {
+                       compatible = "amlogic,simple-framebuffer",
+                                   "simple-framebuffer";
+                       amlogic,pipeline = "vpu-hdmi";
+                       clocks = <&clkc CLKID_HDMI>,
+                                <&clkc CLKID_HTX_PCLK>,
+                                <&clkc CLKID_VPU_INTR>;
+                       status = "disabled";
+               };
        };
 
        efuse: efuse {
@@ -58,6 +49,7 @@
                #address-cells = <1>;
                #size-cells = <1>;
                read-only;
+               secure-monitor = <&sm>;
        };
 
        psci {
                        status = "disabled";
                };
 
+               thermal-zones {
+                       cpu_thermal: cpu-thermal {
+                               polling-delay = <1000>;
+                               polling-delay-passive = <100>;
+                               thermal-sensors = <&cpu_temp>;
+
+                               trips {
+                                       cpu_passive: cpu-passive {
+                                               temperature = <85000>; /* millicelsius */
+                                               hysteresis = <2000>; /* millicelsius */
+                                               type = "passive";
+                                       };
+
+                                       cpu_hot: cpu-hot {
+                                               temperature = <95000>; /* millicelsius */
+                                               hysteresis = <2000>; /* millicelsius */
+                                               type = "hot";
+                                       };
+
+                                       cpu_critical: cpu-critical {
+                                               temperature = <110000>; /* millicelsius */
+                                               hysteresis = <2000>; /* millicelsius */
+                                               type = "critical";
+                                       };
+                               };
+                       };
+
+                       ddr_thermal: ddr-thermal {
+                               polling-delay = <1000>;
+                               polling-delay-passive = <100>;
+                               thermal-sensors = <&ddr_temp>;
+
+                               trips {
+                                       ddr_passive: ddr-passive {
+                                               temperature = <85000>; /* millicelsius */
+                                               hysteresis = <2000>; /* millicelsius */
+                                               type = "passive";
+                                       };
+
+                                       ddr_critical: ddr-critical {
+                                               temperature = <110000>; /* millicelsius */
+                                               hysteresis = <2000>; /* millicelsius */
+                                               type = "critical";
+                                       };
+                               };
+
+                               cooling-maps {
+                                       map {
+                                               trip = <&ddr_passive>;
+                                               cooling-device = <&mali THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                                       };
+                               };
+                       };
+               };
+
                ethmac: ethernet@ff3f0000 {
                        compatible = "amlogic,meson-axg-dwmac",
                                     "snps,dwmac-3.70a",
                                };
                        };
 
+                       cpu_temp: temperature-sensor@34800 {
+                               compatible = "amlogic,g12a-cpu-thermal",
+                                            "amlogic,g12a-thermal";
+                               reg = <0x0 0x34800 0x0 0x50>;
+                               interrupts = <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc CLKID_TS>;
+                               #thermal-sensor-cells = <0>;
+                               amlogic,ao-secure = <&sec_AO>;
+                       };
+
+                       ddr_temp: temperature-sensor@34c00 {
+                               compatible = "amlogic,g12a-ddr-thermal",
+                                            "amlogic,g12a-thermal";
+                               reg = <0x0 0x34c00 0x0 0x50>;
+                               interrupts = <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc CLKID_TS>;
+                               #thermal-sensor-cells = <0>;
+                               amlogic,ao-secure = <&sec_AO>;
+                       };
+
                        usb2_phy0: phy@36000 {
                                compatible = "amlogic,g12a-usb2-phy";
                                reg = <0x0 0x36000 0x0 0x2000>;
                                };
                        };
 
-                       pdm: audio-controller@40000 {
-                               compatible = "amlogic,g12a-pdm",
-                                            "amlogic,axg-pdm";
-                               reg = <0x0 0x40000 0x0 0x34>;
-                               #sound-dai-cells = <0>;
-                               sound-name-prefix = "PDM";
-                               clocks = <&clkc_audio AUD_CLKID_PDM>,
-                                        <&clkc_audio AUD_CLKID_PDM_DCLK>,
-                                        <&clkc_audio AUD_CLKID_PDM_SYSCLK>;
-                               clock-names = "pclk", "dclk", "sysclk";
-                               status = "disabled";
-                       };
-
-                       audio: bus@42000 {
-                               compatible = "simple-bus";
-                               reg = <0x0 0x42000 0x0 0x2000>;
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x42000 0x0 0x2000>;
-
-                               clkc_audio: clock-controller@0 {
-                                       status = "disabled";
-                                       compatible = "amlogic,g12a-audio-clkc";
-                                       reg = <0x0 0x0 0x0 0xb4>;
-                                       #clock-cells = <1>;
-                                       #reset-cells = <1>;
-
-                                       clocks = <&clkc CLKID_AUDIO>,
-                                                <&clkc CLKID_MPLL0>,
-                                                <&clkc CLKID_MPLL1>,
-                                                <&clkc CLKID_MPLL2>,
-                                                <&clkc CLKID_MPLL3>,
-                                                <&clkc CLKID_HIFI_PLL>,
-                                                <&clkc CLKID_FCLK_DIV3>,
-                                                <&clkc CLKID_FCLK_DIV4>,
-                                                <&clkc CLKID_GP0_PLL>;
-                                       clock-names = "pclk",
-                                                     "mst_in0",
-                                                     "mst_in1",
-                                                     "mst_in2",
-                                                     "mst_in3",
-                                                     "mst_in4",
-                                                     "mst_in5",
-                                                     "mst_in6",
-                                                     "mst_in7";
-
-                                       resets = <&reset RESET_AUDIO>;
-                               };
-
-                               toddr_a: audio-controller@100 {
-                                       compatible = "amlogic,g12a-toddr",
-                                                    "amlogic,axg-toddr";
-                                       reg = <0x0 0x100 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "TODDR_A";
-                                       interrupts = <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
-                                       resets = <&arb AXG_ARB_TODDR_A>;
-                                       status = "disabled";
-                               };
-
-                               toddr_b: audio-controller@140 {
-                                       compatible = "amlogic,g12a-toddr",
-                                                    "amlogic,axg-toddr";
-                                       reg = <0x0 0x140 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "TODDR_B";
-                                       interrupts = <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
-                                       resets = <&arb AXG_ARB_TODDR_B>;
-                                       status = "disabled";
-                               };
-
-                               toddr_c: audio-controller@180 {
-                                       compatible = "amlogic,g12a-toddr",
-                                                    "amlogic,axg-toddr";
-                                       reg = <0x0 0x180 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "TODDR_C";
-                                       interrupts = <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
-                                       resets = <&arb AXG_ARB_TODDR_C>;
-                                       status = "disabled";
-                               };
-
-                               frddr_a: audio-controller@1c0 {
-                                       compatible = "amlogic,g12a-frddr",
-                                                    "amlogic,axg-frddr";
-                                       reg = <0x0 0x1c0 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "FRDDR_A";
-                                       interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
-                                       resets = <&arb AXG_ARB_FRDDR_A>;
-                                       status = "disabled";
-                               };
-
-                               frddr_b: audio-controller@200 {
-                                       compatible = "amlogic,g12a-frddr",
-                                                    "amlogic,axg-frddr";
-                                       reg = <0x0 0x200 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "FRDDR_B";
-                                       interrupts = <GIC_SPI 153 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
-                                       resets = <&arb AXG_ARB_FRDDR_B>;
-                                       status = "disabled";
-                               };
-
-                               frddr_c: audio-controller@240 {
-                                       compatible = "amlogic,g12a-frddr",
-                                                    "amlogic,axg-frddr";
-                                       reg = <0x0 0x240 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "FRDDR_C";
-                                       interrupts = <GIC_SPI 154 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
-                                       resets = <&arb AXG_ARB_FRDDR_C>;
-                                       status = "disabled";
-                               };
-
-                               arb: reset-controller@280 {
-                                       status = "disabled";
-                                       compatible = "amlogic,meson-axg-audio-arb";
-                                       reg = <0x0 0x280 0x0 0x4>;
-                                       #reset-cells = <1>;
-                                       clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
-                               };
-
-                               tdmin_a: audio-controller@300 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x300 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_A";
-                                       resets = <&clkc_audio AUD_RESET_TDMIN_A>;
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmin_b: audio-controller@340 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x340 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_B";
-                                       resets = <&clkc_audio AUD_RESET_TDMIN_B>;
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmin_c: audio-controller@380 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x380 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_C";
-                                       resets = <&clkc_audio AUD_RESET_TDMIN_C>;
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmin_lb: audio-controller@3c0 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x3c0 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_LB";
-                                       resets = <&clkc_audio AUD_RESET_TDMIN_LB>;
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               spdifin: audio-controller@400 {
-                                       compatible = "amlogic,g12a-spdifin",
-                                                    "amlogic,axg-spdifin";
-                                       reg = <0x0 0x400 0x0 0x30>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "SPDIFIN";
-                                       interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
-                                                <&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
-                                       clock-names = "pclk", "refclk";
-                                       status = "disabled";
-                               };
-
-                               spdifout: audio-controller@480 {
-                                       compatible = "amlogic,g12a-spdifout",
-                                                    "amlogic,axg-spdifout";
-                                       reg = <0x0 0x480 0x0 0x50>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "SPDIFOUT";
-                                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
-                                                <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
-                                       clock-names = "pclk", "mclk";
-                                       status = "disabled";
-                               };
-
-                               tdmout_a: audio-controller@500 {
-                                       compatible = "amlogic,g12a-tdmout";
-                                       reg = <0x0 0x500 0x0 0x40>;
-                                       sound-name-prefix = "TDMOUT_A";
-                                       resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
-                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmout_b: audio-controller@540 {
-                                       compatible = "amlogic,g12a-tdmout";
-                                       reg = <0x0 0x540 0x0 0x40>;
-                                       sound-name-prefix = "TDMOUT_B";
-                                       resets = <&clkc_audio AUD_RESET_TDMOUT_B>;
-                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmout_c: audio-controller@580 {
-                                       compatible = "amlogic,g12a-tdmout";
-                                       reg = <0x0 0x580 0x0 0x40>;
-                                       sound-name-prefix = "TDMOUT_C";
-                                       resets = <&clkc_audio AUD_RESET_TDMOUT_C>;
-                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               spdifout_b: audio-controller@680 {
-                                       compatible = "amlogic,g12a-spdifout",
-                                                    "amlogic,axg-spdifout";
-                                       reg = <0x0 0x680 0x0 0x50>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "SPDIFOUT_B";
-                                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT_B>,
-                                                <&clkc_audio AUD_CLKID_SPDIFOUT_B_CLK>;
-                                       clock-names = "pclk", "mclk";
-                                       status = "disabled";
-                               };
-
-                               tohdmitx: audio-controller@744 {
-                                       compatible = "amlogic,g12a-tohdmitx";
-                                       reg = <0x0 0x744 0x0 0x4>;
-                                       #sound-dai-cells = <1>;
-                                       sound-name-prefix = "TOHDMITX";
-                                       status = "disabled";
-                               };
-                       };
-
                        usb3_pcie_phy: phy@46000 {
                                compatible = "amlogic,g12a-usb3-pcie-phy";
                                reg = <0x0 0x46000 0x0 0x2000>;
                        compatible = "amlogic,meson-g12a-mali", "arm,mali-bifrost";
                        reg = <0x0 0xffe40000 0x0 0x40000>;
                        interrupt-parent = <&gic>;
-                       interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+                       interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "gpu", "mmu", "job";
+                                    <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "job", "mmu", "gpu";
                        clocks = <&clkc CLKID_MALI>;
                        resets = <&reset RESET_DVALIN_CAPB3>, <&reset RESET_DVALIN>;
 
                        assigned-clock-rates = <0>, /* Do Nothing */
                                               <800000000>,
                                               <0>; /* Do Nothing */
+                       #cooling-cells = <2>;
                };
        };
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
new file mode 100644 (file)
index 0000000..b3ba2fd
--- /dev/null
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#include "meson-g12-common.dtsi"
+#include <dt-bindings/clock/axg-audio-clkc.h>
+#include <dt-bindings/power/meson-g12a-power.h>
+#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+#include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h>
+
+/ {
+       tdmif_a: audio-controller-0 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_A";
+               clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_b: audio-controller-1 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_B";
+               clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_c: audio-controller-2 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_C";
+               clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+};
+
+&apb {
+       pdm: audio-controller@40000 {
+               compatible = "amlogic,g12a-pdm",
+                            "amlogic,axg-pdm";
+               reg = <0x0 0x40000 0x0 0x34>;
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "PDM";
+               clocks = <&clkc_audio AUD_CLKID_PDM>,
+                        <&clkc_audio AUD_CLKID_PDM_DCLK>,
+                        <&clkc_audio AUD_CLKID_PDM_SYSCLK>;
+               clock-names = "pclk", "dclk", "sysclk";
+               status = "disabled";
+       };
+
+       audio: bus@42000 {
+               compatible = "simple-bus";
+               reg = <0x0 0x42000 0x0 0x2000>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges = <0x0 0x0 0x0 0x42000 0x0 0x2000>;
+
+               clkc_audio: clock-controller@0 {
+                       status = "disabled";
+                       compatible = "amlogic,g12a-audio-clkc";
+                       reg = <0x0 0x0 0x0 0xb4>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+
+                       clocks = <&clkc CLKID_AUDIO>,
+                                <&clkc CLKID_MPLL0>,
+                                <&clkc CLKID_MPLL1>,
+                                <&clkc CLKID_MPLL2>,
+                                <&clkc CLKID_MPLL3>,
+                                <&clkc CLKID_HIFI_PLL>,
+                                <&clkc CLKID_FCLK_DIV3>,
+                                <&clkc CLKID_FCLK_DIV4>,
+                                <&clkc CLKID_GP0_PLL>;
+                       clock-names = "pclk",
+                                     "mst_in0",
+                                     "mst_in1",
+                                     "mst_in2",
+                                     "mst_in3",
+                                     "mst_in4",
+                                     "mst_in5",
+                                     "mst_in6",
+                                     "mst_in7";
+
+                       resets = <&reset RESET_AUDIO>;
+               };
+
+               toddr_a: audio-controller@100 {
+                       compatible = "amlogic,g12a-toddr",
+                                    "amlogic,axg-toddr";
+                       reg = <0x0 0x100 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "TODDR_A";
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
+                       resets = <&arb AXG_ARB_TODDR_A>,
+                                <&clkc_audio AUD_RESET_TODDR_A>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               toddr_b: audio-controller@140 {
+                       compatible = "amlogic,g12a-toddr",
+                                    "amlogic,axg-toddr";
+                       reg = <0x0 0x140 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "TODDR_B";
+                       interrupts = <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
+                       resets = <&arb AXG_ARB_TODDR_B>,
+                                <&clkc_audio AUD_RESET_TODDR_B>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               toddr_c: audio-controller@180 {
+                       compatible = "amlogic,g12a-toddr",
+                                    "amlogic,axg-toddr";
+                       reg = <0x0 0x180 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "TODDR_C";
+                       interrupts = <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
+                       resets = <&arb AXG_ARB_TODDR_C>,
+                                <&clkc_audio AUD_RESET_TODDR_C>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               frddr_a: audio-controller@1c0 {
+                       compatible = "amlogic,g12a-frddr",
+                                    "amlogic,axg-frddr";
+                       reg = <0x0 0x1c0 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "FRDDR_A";
+                       interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
+                       resets = <&arb AXG_ARB_FRDDR_A>,
+                                <&clkc_audio AUD_RESET_FRDDR_A>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               frddr_b: audio-controller@200 {
+                       compatible = "amlogic,g12a-frddr",
+                                    "amlogic,axg-frddr";
+                       reg = <0x0 0x200 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "FRDDR_B";
+                       interrupts = <GIC_SPI 153 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
+                       resets = <&arb AXG_ARB_FRDDR_B>,
+                                <&clkc_audio AUD_RESET_FRDDR_B>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               frddr_c: audio-controller@240 {
+                       compatible = "amlogic,g12a-frddr",
+                                    "amlogic,axg-frddr";
+                       reg = <0x0 0x240 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "FRDDR_C";
+                       interrupts = <GIC_SPI 154 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
+                       resets = <&arb AXG_ARB_FRDDR_C>,
+                                <&clkc_audio AUD_RESET_FRDDR_C>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               arb: reset-controller@280 {
+                       status = "disabled";
+                       compatible = "amlogic,meson-axg-audio-arb";
+                       reg = <0x0 0x280 0x0 0x4>;
+                       #reset-cells = <1>;
+                       clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
+               };
+
+               tdmin_a: audio-controller@300 {
+                       compatible = "amlogic,g12a-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x300 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_A";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_A>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmin_b: audio-controller@340 {
+                       compatible = "amlogic,g12a-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x340 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_B";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_B>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmin_c: audio-controller@380 {
+                       compatible = "amlogic,g12a-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x380 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_C";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_C>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmin_lb: audio-controller@3c0 {
+                       compatible = "amlogic,g12a-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x3c0 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_LB";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_LB>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               spdifin: audio-controller@400 {
+                       compatible = "amlogic,g12a-spdifin",
+                                    "amlogic,axg-spdifin";
+                       reg = <0x0 0x400 0x0 0x30>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "SPDIFIN";
+                       interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
+                                <&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
+                       clock-names = "pclk", "refclk";
+                       resets = <&clkc_audio AUD_RESET_SPDIFIN>;
+                       status = "disabled";
+               };
+
+               spdifout: audio-controller@480 {
+                       compatible = "amlogic,g12a-spdifout",
+                                    "amlogic,axg-spdifout";
+                       reg = <0x0 0x480 0x0 0x50>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "SPDIFOUT";
+                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+                                <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+                       clock-names = "pclk", "mclk";
+                       resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
+                       status = "disabled";
+               };
+
+               tdmout_a: audio-controller@500 {
+                       compatible = "amlogic,g12a-tdmout";
+                       reg = <0x0 0x500 0x0 0x40>;
+                       sound-name-prefix = "TDMOUT_A";
+                       resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmout_b: audio-controller@540 {
+                       compatible = "amlogic,g12a-tdmout";
+                       reg = <0x0 0x540 0x0 0x40>;
+                       sound-name-prefix = "TDMOUT_B";
+                       resets = <&clkc_audio AUD_RESET_TDMOUT_B>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmout_c: audio-controller@580 {
+                       compatible = "amlogic,g12a-tdmout";
+                       reg = <0x0 0x580 0x0 0x40>;
+                       sound-name-prefix = "TDMOUT_C";
+                       resets = <&clkc_audio AUD_RESET_TDMOUT_C>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               spdifout_b: audio-controller@680 {
+                       compatible = "amlogic,g12a-spdifout",
+                                    "amlogic,axg-spdifout";
+                       reg = <0x0 0x680 0x0 0x50>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "SPDIFOUT_B";
+                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT_B>,
+                                <&clkc_audio AUD_CLKID_SPDIFOUT_B_CLK>;
+                       clock-names = "pclk", "mclk";
+                       resets = <&clkc_audio AUD_RESET_SPDIFOUT_B>;
+                       status = "disabled";
+               };
+
+               tohdmitx: audio-controller@744 {
+                       compatible = "amlogic,g12a-tohdmitx";
+                       reg = <0x0 0x744 0x0 0x4>;
+                       #sound-dai-cells = <1>;
+                       sound-name-prefix = "TOHDMITX";
+                       resets = <&clkc_audio AUD_RESET_TOHDMITX>;
+                       status = "disabled";
+               };
+       };
+};
+
+&cpu_thermal {
+       cooling-maps {
+               map0 {
+                       trip = <&cpu_passive>;
+                       cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu102 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu103 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+               };
+               map1 {
+                       trip = <&cpu_hot>;
+                       cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu102 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                        <&cpu103 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+               };
+       };
+};
+
+&ethmac {
+       power-domains = <&pwrc PWRC_G12A_ETH_ID>;
+};
+
+&vpu {
+       power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
+
+&sd_emmc_a {
+       amlogic,dram-access-quirk;
+};
+
+&simplefb_cvbs {
+       power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
+
+&simplefb_hdmi {
+       power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
+
index c9fa23a..2ac9e3a 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 17155fb..4f2596d 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index eb5d177..fb0ab27 100644 (file)
@@ -3,8 +3,7 @@
  * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
  */
 
-#include "meson-g12-common.dtsi"
-#include <dt-bindings/power/meson-g12a-power.h>
+#include "meson-g12.dtsi"
 
 / {
        compatible = "amlogic,g12a";
@@ -19,6 +18,7 @@
                        reg = <0x0 0x0>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu1: cpu@1 {
@@ -27,6 +27,7 @@
                        reg = <0x0 0x1>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu2: cpu@2 {
@@ -35,6 +36,7 @@
                        reg = <0x0 0x2>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu3: cpu@3 {
@@ -43,6 +45,7 @@
                        reg = <0x0 0x3>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                l2: l2-cache0 {
        };
 };
 
-&ethmac {
-       power-domains = <&pwrc PWRC_G12A_ETH_ID>;
-};
-
-&vpu {
-       power-domains = <&pwrc PWRC_G12A_VPU_ID>;
-};
+&cpu_thermal {
+       cooling-maps {
+               map0 {
+                       trip = <&cpu_passive>;
+                       cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                       <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                       <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                       <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+               };
 
-&sd_emmc_a {
-       amlogic,dram-access-quirk;
+               map1 {
+                       trip = <&cpu_hot>;
+                       cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                       <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                       <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                       <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+               };
+       };
 };
index 42f1540..0e54c1d 100644 (file)
@@ -12,7 +12,7 @@
 #include <dt-bindings/sound/meson-g12a-tohdmitx.h>
 
 / {
-       compatible = "hardkernel,odroid-n2", "amlogic,g12b";
+       compatible = "hardkernel,odroid-n2", "amlogic,s922x", "amlogic,g12b";
        model = "Hardkernel ODROID-N2";
 
        aliases {
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-ugoos-am6.dts
new file mode 100644 (file)
index 0000000..ccd0bce
--- /dev/null
@@ -0,0 +1,557 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b.dtsi"
+#include "meson-g12b-s922x.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+       compatible = "ugoos,am6", "amlogic,g12b";
+       model = "Ugoos AM6";
+
+       aliases {
+               serial0 = &uart_AO;
+               ethernet0 = &ethmac;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x40000000>;
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+               clocks = <&wifi32k>;
+               clock-names = "ext_clock";
+       };
+
+       spdif_dit: audio-codec-1 {
+               #sound-dai-cells = <0>;
+               compatible = "linux,spdif-dit";
+               status = "okay";
+               sound-name-prefix = "DIT";
+       };
+
+       flash_1v8: regulator-flash_1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "FLASH_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_3v3>;
+               regulator-always-on;
+       };
+
+       main_12v: regulator-main_12v {
+               compatible = "regulator-fixed";
+               regulator-name = "12V";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-always-on;
+       };
+
+       vcc_5v: regulator-vcc_5v {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&main_12v>;
+
+               gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+               enable-active-high;
+       };
+
+       vcc_1v8: regulator-vcc_1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_3v3>;
+               regulator-always-on;
+       };
+
+       vcc_3v3: regulator-vcc_3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vddao_3v3>;
+               regulator-always-on;
+               /* FIXME: actually controlled by VDDCPU_B_EN */
+       };
+
+       vddcpu_a: regulator-vddcpu-a {
+               /*
+                * MP1653 Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU_A";
+               regulator-min-microvolt = <721000>;
+               regulator-max-microvolt = <1022000>;
+
+               vin-supply = <&main_12v>;
+
+               pwms = <&pwm_ab 0 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vddcpu_b: regulator-vddcpu-b {
+               /*
+                * MP1652 Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU_B";
+               regulator-min-microvolt = <721000>;
+               regulator-max-microvolt = <1022000>;
+
+               vin-supply = <&main_12v>;
+
+               pwms = <&pwm_AO_cd 1 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       usb1_pow: regulator-usb1-pow {
+               compatible = "regulator-fixed";
+               regulator-name = "USB1_POW";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc_5v>;
+
+               /* connected to SY6280A Power Switch */
+               gpio = <&gpio GPIOA_8 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       usb_pwr_en: regulator-usb-pwr-en {
+               compatible = "regulator-fixed";
+               regulator-name = "USB_PWR_EN";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc_5v>;
+
+               /* Connected to USB3 Type-A Port power enable */
+               gpio = <&gpio GPIOAO_7 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vddao_1v8: regulator-vddao-1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDAO_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vddao_3v3>;
+               regulator-always-on;
+       };
+
+       vddao_3v3: regulator-vddao-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDAO_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&main_12v>;
+               regulator-always-on;
+       };
+
+       cvbs-connector {
+               compatible = "composite-video-connector";
+
+               port {
+                       cvbs_connector_in: endpoint {
+                               remote-endpoint = <&cvbs_vdac_out>;
+                       };
+               };
+       };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+
+       sound {
+               compatible = "amlogic,axg-sound-card";
+               model = "G12B-UGOOS-AM6";
+               audio-aux-devs = <&tdmout_b>;
+               audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+                               "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+                               "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+                               "TDM_B Playback", "TDMOUT_B OUT",
+                               "SPDIFOUT IN 0", "FRDDR_A OUT 3",
+                               "SPDIFOUT IN 1", "FRDDR_B OUT 3",
+                               "SPDIFOUT IN 2", "FRDDR_C OUT 3";
+
+               assigned-clocks = <&clkc CLKID_MPLL2>,
+                                 <&clkc CLKID_MPLL0>,
+                                 <&clkc CLKID_MPLL1>;
+               assigned-clock-parents = <0>, <0>, <0>;
+               assigned-clock-rates = <294912000>,
+                                      <270950400>,
+                                      <393216000>;
+               status = "okay";
+
+               dai-link-0 {
+                       sound-dai = <&frddr_a>;
+               };
+
+               dai-link-1 {
+                       sound-dai = <&frddr_b>;
+               };
+
+               dai-link-2 {
+                       sound-dai = <&frddr_c>;
+               };
+
+               /* 8ch hdmi interface */
+               dai-link-3 {
+                       sound-dai = <&tdmif_b>;
+                       dai-format = "i2s";
+                       dai-tdm-slot-tx-mask-0 = <1 1>;
+                       dai-tdm-slot-tx-mask-1 = <1 1>;
+                       dai-tdm-slot-tx-mask-2 = <1 1>;
+                       dai-tdm-slot-tx-mask-3 = <1 1>;
+                       mclk-fs = <256>;
+
+                       codec {
+                               sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+                       };
+               };
+
+               /* spdif hdmi or toslink interface */
+               dai-link-4 {
+                       sound-dai = <&spdifout>;
+
+                       codec-0 {
+                               sound-dai = <&spdif_dit>;
+                       };
+
+                       codec-1 {
+                               sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_A>;
+                       };
+               };
+
+               /* spdif hdmi interface */
+               dai-link-5 {
+                       sound-dai = <&spdifout_b>;
+
+                       codec {
+                               sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_B>;
+                       };
+               };
+
+               /* hdmi glue */
+               dai-link-6 {
+                       sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+                       codec {
+                               sound-dai = <&hdmi_tx>;
+                       };
+               };
+       };
+
+       wifi32k: wifi32k {
+               compatible = "pwm-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+       };
+};
+
+&arb {
+       status = "okay";
+};
+
+&cec_AO {
+       pinctrl-0 = <&cec_ao_a_h_pins>;
+       pinctrl-names = "default";
+       status = "disabled";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+       pinctrl-0 = <&cec_ao_b_h_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+       status = "okay";
+};
+
+&cpu0 {
+       cpu-supply = <&vddcpu_b>;
+       operating-points-v2 = <&cpu_opp_table_0>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu_b>;
+       operating-points-v2 = <&cpu_opp_table_0>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu100 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu101 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu102 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu103 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+       cvbs_vdac_out: endpoint {
+               remote-endpoint = <&cvbs_connector_in>;
+       };
+};
+
+&ext_mdio {
+       external_phy: ethernet-phy@0 {
+               /* Realtek RTL8211F (0x001cc916) */
+               reg = <0>;
+               max-speed = <1000>;
+
+               reset-assert-us = <10000>;
+               reset-deassert-us = <30000>;
+               reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+               interrupt-parent = <&gpio_intc>;
+               /* MAC_INTR on GPIOZ_14 */
+               interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
+&ethmac {
+       pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+       phy-mode = "rgmii";
+       phy-handle = <&external_phy>;
+       amlogic,tx-delay-ns = <2>;
+};
+
+&frddr_a {
+       status = "okay";
+};
+
+&frddr_b {
+       status = "okay";
+};
+
+&frddr_c {
+       status = "okay";
+};
+
+&hdmi_tx {
+       status = "okay";
+       pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+       pinctrl-names = "default";
+       hdmi-supply = <&vcc_5v>;
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
+&ir {
+       status = "okay";
+       pinctrl-0 = <&remote_input_ao_pins>;
+       pinctrl-names = "default";
+       linux,rc-map-name = "rc-khadas";
+};
+
+&pwm_ab {
+       pinctrl-0 = <&pwm_a_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin0";
+       status = "okay";
+};
+
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
+};
+
+&pwm_ef {
+       pinctrl-0 = <&pwm_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin0";
+       status = "okay";
+};
+
+/* SDIO */
+&sd_emmc_a {
+       status = "okay";
+       pinctrl-0 = <&sdio_pins>;
+       pinctrl-1 = <&sdio_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       sd-uhs-sdr50;
+       max-frequency = <100000000>;
+
+       non-removable;
+       disable-wp;
+
+       mmc-pwrseq = <&sdio_pwrseq>;
+
+       vmmc-supply = <&vddao_3v3>;
+       vqmmc-supply = <&vddao_1v8>;
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
+
+/* SD card */
+&sd_emmc_b {
+       status = "okay";
+       pinctrl-0 = <&sdcard_c_pins>;
+       pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       max-frequency = <50000000>;
+       disable-wp;
+
+       cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&vddao_3v3>;
+       vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+       status = "okay";
+       pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       max-frequency = <100000000>;
+       disable-wp;
+
+       mmc-pwrseq = <&emmc_pwrseq>;
+       vmmc-supply = <&vcc_3v3>;
+       vqmmc-supply = <&flash_1v8>;
+};
+
+&spdifout {
+       pinctrl-0 = <&spdif_out_h_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&spdifout_b {
+       status = "okay";
+};
+
+&tdmif_b {
+       status = "okay";
+};
+
+&tdmout_b {
+       status = "okay";
+};
+
+&tohdmitx {
+       status = "okay";
+};
+
+&uart_A {
+       status = "okay";
+       pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+       pinctrl-names = "default";
+       uart-has-rtscts;
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+               max-speed = <2000000>;
+               clocks = <&wifi32k>;
+       clock-names = "lpo";
+       };
+};
+
+&uart_AO {
+       status = "okay";
+       pinctrl-0 = <&uart_ao_a_pins>;
+       pinctrl-names = "default";
+};
+
+&usb {
+       status = "okay";
+       dr_mode = "host";
+       vbus-regulator = <&usb_pwr_en>;
+};
+
+&usb2_phy0 {
+       phy-supply = <&usb1_pow>;
+};
+
+&usb2_phy1 {
+       phy-supply = <&usb1_pow>;
+};
index 5628ccd..6dbc396 100644 (file)
@@ -4,8 +4,7 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-g12-common.dtsi"
-#include <dt-bindings/power/meson-g12a-power.h>
+#include "meson-g12.dtsi"
 
 / {
        compatible = "amlogic,g12b";
@@ -49,7 +48,9 @@
                        compatible = "arm,cortex-a53";
                        reg = <0x0 0x0>;
                        enable-method = "psci";
+                       capacity-dmips-mhz = <592>;
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu1: cpu@1 {
@@ -57,7 +58,9 @@
                        compatible = "arm,cortex-a53";
                        reg = <0x0 0x1>;
                        enable-method = "psci";
+                       capacity-dmips-mhz = <592>;
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu100: cpu@100 {
@@ -65,7 +68,9 @@
                        compatible = "arm,cortex-a73";
                        reg = <0x0 0x100>;
                        enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu101: cpu@101 {
@@ -73,7 +78,9 @@
                        compatible = "arm,cortex-a73";
                        reg = <0x0 0x101>;
                        enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu102: cpu@102 {
@@ -81,7 +88,9 @@
                        compatible = "arm,cortex-a73";
                        reg = <0x0 0x102>;
                        enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                cpu103: cpu@103 {
@@ -89,7 +98,9 @@
                        compatible = "arm,cortex-a73";
                        reg = <0x0 0x103>;
                        enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
                        next-level-cache = <&l2>;
+                       #cooling-cells = <2>;
                };
 
                l2: l2-cache0 {
        compatible = "amlogic,g12b-clkc";
 };
 
-&ethmac {
-       power-domains = <&pwrc PWRC_G12A_ETH_ID>;
-};
-
-&vpu {
-       power-domains = <&pwrc PWRC_G12A_VPU_ID>;
-};
-
-&sd_emmc_a {
-       amlogic,dram-access-quirk;
-};
index a9b7785..12d5e33 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 6733050..40db06e 100644 (file)
                #address-cells = <1>;
                #size-cells = <1>;
                read-only;
+               secure-monitor = <&sm>;
 
                sn: sn@14 {
                        reg = <0x14 0x10>;
                        };
 
                        i2c_A: i2c@8500 {
-                               compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c";
+                               compatible = "amlogic,meson-gxbb-i2c";
                                reg = <0x0 0x08500 0x0 0x20>;
                                interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
                                #address-cells = <1>;
                        };
 
                        i2c_B: i2c@87c0 {
-                               compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c";
+                               compatible = "amlogic,meson-gxbb-i2c";
                                reg = <0x0 0x087c0 0x0 0x20>;
                                interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
                                #address-cells = <1>;
                        };
 
                        i2c_C: i2c@87e0 {
-                               compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c";
+                               compatible = "amlogic,meson-gxbb-i2c";
                                reg = <0x0 0x087e0 0x0 0x20>;
                                interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
                                #address-cells = <1>;
                                compatible = "amlogic,meson-gx-ao-cec";
                                reg = <0x0 0x00100 0x0 0x14>;
                                interrupts = <GIC_SPI 199 IRQ_TYPE_EDGE_RISING>;
+                               status = "disabled";
                        };
 
                        sec_AO: ao-secure@140 {
                        };
 
                        i2c_AO: i2c@500 {
-                               compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c";
+                               compatible = "amlogic,meson-gxbb-i2c";
                                reg = <0x0 0x500 0x0 0x20>;
                                interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
                                #address-cells = <1>;
index 233eb1c..d6ca684 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddio_ao3v3>;
index afcf8a9..65ec7de 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 6039add..6ded279 100644 (file)
                regulator-min-microvolt = <5000000>;
                regulator-max-microvolt = <5000000>;
 
+               /*
+                * signal name from schematics: PWREN
+                */
                gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
                enable-active-high;
+               /*
+                * signal name from schematics: USB_POWER
+                */
+               vin-supply = <&p5v0>;
        };
 
        leds {
                };
        };
 
+       p5v0: regulator-p5v0 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "P5V0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       hdmi_p5v0: regulator-hdmi_p5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "HDMI_P5V0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               /* AP2331SA-7 */
+               vin-supply = <&p5v0>;
+       };
+
        tflash_vdd: regulator-tflash_vdd {
-               /*
-                * signal name from schematics: TFLASH_VDD_EN
-                */
                compatible = "regulator-fixed";
 
                regulator-name = "TFLASH_VDD";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
 
+               /*
+                * signal name from schematics: TFLASH_VDD_EN
+                */
                gpio = <&gpio GPIOY_12 GPIO_ACTIVE_HIGH>;
                enable-active-high;
+               /* U16 RT9179GB */
+               vin-supply = <&vddio_ao3v3>;
        };
 
        tf_io: gpio-regulator-tf_io {
 
                states = <3300000 0>,
                         <1800000 1>;
+               /* U12/U13 RT9179GB */
+               vin-supply = <&vddio_ao3v3>;
        };
 
        vcc1v8: regulator-vcc1v8 {
                regulator-name = "VCC1V8";
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               /* U18 RT9179GB */
+               vin-supply = <&vddio_ao3v3>;
        };
 
        vcc3v3: regulator-vcc3v3 {
                regulator-max-microvolt = <3300000>;
        };
 
+       vddio_ao1v8: regulator-vddio-ao1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               /* U17 RT9179GB */
+               vin-supply = <&p5v0>;
+       };
+
+       vddio_ao3v3: regulator-vddio-ao3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               /* U11 MP2161GJ-C499 */
+               vin-supply = <&p5v0>;
+       };
+
+       ddr3_1v5: regulator-ddr3_1v5 {
+               compatible = "regulator-fixed";
+               regulator-name = "DDR3_1V5";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+               regulator-always-on;
+               /* U15 MP2161GJ-C499 */
+               vin-supply = <&p5v0>;
+       };
+
        emmc_pwrseq: emmc-pwrseq {
                compatible = "mmc-pwrseq-emmc";
                reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
        status = "okay";
        pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
        pinctrl-names = "default";
+       hdmi-supply = <&hdmi_p5v0>;
 };
 
 &hdmi_tx_tmds_port {
 };
 
 &usb0_phy {
-       status = "okay";
+       status = "disabled";
        phy-supply = <&usb_otg_pwr>;
 };
 
 };
 
 &usb0 {
-       status = "okay";
+       status = "disabled";
 };
 
 &usb1 {
index 89f7b41..e803a46 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 43b11e3..5eab3df 100644 (file)
        status = "okay";
        pinctrl-0 = <&remote_input_ao_pins>;
        pinctrl-names = "default";
+       linux,rc-map-name = "rc-vega-s9x";
 };
 
 &pwm_ef {
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 4c53988..dee51cf 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 82b1c48..4d59494 100644 (file)
@@ -14,7 +14,7 @@
 / {
        compatible = "libretech,aml-s805x-ac", "amlogic,s805x",
                     "amlogic,meson-gxl";
-       model = "Libre Computer Board AML-S805X-AC";
+       model = "Libre Computer AML-S805X-AC";
 
        aliases {
                serial0 = &uart_AO;
index 3a1484e..a1119cf 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 2a5cd30..440bc23 100644 (file)
 
        gpio-keys-polled {
                compatible = "gpio-keys-polled";
-               #address-cells = <1>;
-               #size-cells = <0>;
                poll-interval = <100>;
 
-               button@0 {
+               power-button {
                        label = "power";
                        linux,code = <KEY_POWER>;
                        gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
        bluetooth {
                compatible = "brcm,bcm43438-bt";
                shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+               max-speed = <2000000>;
+               clocks = <&wifi32k>;
+               clock-names = "lpo";
        };
 };
 
index 4b8ce73..e8348b2 100644 (file)
@@ -12,8 +12,9 @@
 #include "meson-gxl-s905x.dtsi"
 
 / {
-       compatible = "libretech,cc", "amlogic,s905x", "amlogic,meson-gxl";
-       model = "Libre Computer Board AML-S905X-CC";
+       compatible = "libretech,aml-s905x-cc", "amlogic,s905x",
+                    "amlogic,meson-gxl";
+       model = "Libre Computer AML-S905X-CC";
 
        aliases {
                serial0 = &uart_AO;
index c433a03..62dd878 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index e3c16f5..43eb7d1 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index 49ff0a7..ed33d8e 100644 (file)
                                phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>;
                        };
                };
+
+               crypto: crypto@c883e000 {
+                       compatible = "amlogic,gxl-crypto";
+                       reg = <0x0 0xc883e000 0x0 0x36>;
+                       interrupts = <GIC_SPI 188 IRQ_TYPE_EDGE_RISING>,
+                                    <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc CLKID_BLKMV>;
+                       clock-names = "blkmv";
+                       status = "okay";
+               };
        };
 };
 
index f25ddd1..f82f25c 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
        bluetooth {
                compatible = "brcm,bcm43438-bt";
                shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+               max-speed = <2000000>;
+               clocks = <&wifi32k>;
+               clock-names = "lpo";
        };
 };
 
index 5cd4d35..420a88e 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
index e2ea675..0bdf51d 100644 (file)
@@ -35,3 +35,7 @@
                reg = <0>;
        };
 };
+
+&ir {
+       linux,rc-map-name = "rc-vega-s9x";
+};
index a0e677d..5ff64a0 100644 (file)
                compatible = "amlogic,meson-gxm-mali", "arm,mali-t820";
                reg = <0x0 0xc0000 0x0 0x40000>;
                interrupt-parent = <&gic>;
-               interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+               interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-names = "gpu", "mmu", "job";
+                            <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "job", "mmu", "gpu";
                clocks = <&clkc CLKID_MALI>;
                resets = <&reset RESET_MALI_CAPB3>, <&reset RESET_MALI>;
 
index eac5720..90815fa 100644 (file)
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vsys_3v3>;
index 3435aaa..5bd0746 100644 (file)
@@ -9,6 +9,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
 
 / {
        compatible = "seirobotics,sei610", "amlogic,sm1";
                ethernet0 = &ethmac;
        };
 
+       mono_dac: audio-codec-0 {
+               compatible = "maxim,max98357a";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "U16";
+               sdmode-gpios = <&gpio GPIOX_8 GPIO_ACTIVE_HIGH>;
+       };
+
+       dmics: audio-codec-1 {
+               #sound-dai-cells = <0>;
+               compatible = "dmic-codec";
+               num-channels = <2>;
+               wakeup-delay-ms = <50>;
+               status = "okay";
+               sound-name-prefix = "MIC";
+       };
+
        chosen {
                stdout-path = "serial0:115200n8";
        };
                clock-names = "ext_clock";
        };
 
+       sound {
+               compatible = "amlogic,axg-sound-card";
+               model = "SM1-SEI610";
+               audio-aux-devs = <&tdmout_a>, <&tdmout_b>,
+                                <&tdmin_a>, <&tdmin_b>;
+               audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0",
+                               "TDMOUT_A IN 1", "FRDDR_B OUT 0",
+                               "TDMOUT_A IN 2", "FRDDR_C OUT 0",
+                               "TDM_A Playback", "TDMOUT_A OUT",
+                               "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+                               "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+                               "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+                               "TDM_B Playback", "TDMOUT_B OUT",
+                               "TODDR_A IN 4", "PDM Capture",
+                               "TODDR_B IN 4", "PDM Capture",
+                               "TODDR_C IN 4", "PDM Capture",
+                               "TDMIN_A IN 0", "TDM_A Capture",
+                               "TDMIN_A IN 3", "TDM_A Loopback",
+                               "TDMIN_B IN 0", "TDM_A Capture",
+                               "TDMIN_B IN 3", "TDM_A Loopback",
+                               "TDMIN_A IN 1", "TDM_B Capture",
+                               "TDMIN_A IN 4", "TDM_B Loopback",
+                               "TDMIN_B IN 1", "TDM_B Capture",
+                               "TDMIN_B IN 4", "TDM_B Loopback",
+                               "TODDR_A IN 0", "TDMIN_A OUT",
+                               "TODDR_B IN 0", "TDMIN_A OUT",
+                               "TODDR_C IN 0", "TDMIN_A OUT",
+                               "TODDR_A IN 1", "TDMIN_B OUT",
+                               "TODDR_B IN 1", "TDMIN_B OUT",
+                               "TODDR_C IN 1", "TDMIN_B OUT";
+
+               assigned-clocks = <&clkc CLKID_MPLL2>,
+                                 <&clkc CLKID_MPLL0>,
+                                 <&clkc CLKID_MPLL1>;
+               assigned-clock-parents = <0>, <0>, <0>;
+               assigned-clock-rates = <294912000>,
+                                      <270950400>,
+                                      <393216000>;
+               status = "okay";
+
+               dai-link-0 {
+                       sound-dai = <&frddr_a>;
+               };
+
+               dai-link-1 {
+                       sound-dai = <&frddr_b>;
+               };
+
+               dai-link-2 {
+                       sound-dai = <&frddr_c>;
+               };
+
+               dai-link-3 {
+                       sound-dai = <&toddr_a>;
+               };
+
+               dai-link-4 {
+                       sound-dai = <&toddr_b>;
+               };
+
+               dai-link-5 {
+                       sound-dai = <&toddr_c>;
+               };
+
+               /* internal speaker interface */
+               dai-link-6 {
+                       sound-dai = <&tdmif_a>;
+                       dai-format = "i2s";
+                       dai-tdm-slot-tx-mask-0 = <1 1>;
+                       mclk-fs = <256>;
+
+                       codec-0 {
+                               sound-dai = <&mono_dac>;
+                       };
+
+                       codec-1 {
+                               sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>;
+                       };
+               };
+
+               /* 8ch hdmi interface */
+               dai-link-7 {
+                       sound-dai = <&tdmif_b>;
+                       dai-format = "i2s";
+                       dai-tdm-slot-tx-mask-0 = <1 1>;
+                       dai-tdm-slot-tx-mask-1 = <1 1>;
+                       dai-tdm-slot-tx-mask-2 = <1 1>;
+                       dai-tdm-slot-tx-mask-3 = <1 1>;
+                       mclk-fs = <256>;
+
+                       codec {
+                               sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+                       };
+               };
+
+               /* internal digital mics */
+               dai-link-8 {
+                       sound-dai = <&pdm>;
+
+                       codec {
+                               sound-dai = <&dmics>;
+                       };
+               };
+
+               /* hdmi glue */
+               dai-link-9 {
+                       sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+                       codec {
+                               sound-dai = <&hdmi_tx>;
+                       };
+               };
+       };
+
        wifi32k: wifi32k {
                compatible = "pwm-clock";
                #clock-cells = <0>;
        };
 };
 
+&arb {
+       status = "okay";
+};
+
 &cec_AO {
        pinctrl-0 = <&cec_ao_a_h_pins>;
        pinctrl-names = "default";
        hdmi-phandle = <&hdmi_tx>;
 };
 
+&clkc_audio {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&vddcpu>;
        operating-points-v2 = <&cpu_opp_table>;
        phy-mode = "rmii";
 };
 
+&frddr_a {
+       status = "okay";
+};
+
+&frddr_b {
+       status = "okay";
+};
+
+&frddr_c {
+       status = "okay";
+};
+
 &hdmi_tx {
        status = "okay";
        pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
        pinctrl-names = "default";
 };
 
+&pdm {
+       pinctrl-0 = <&pdm_din0_z_pins>, <&pdm_dclk_z_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
 &pwm_AO_ab {
        status = "okay";
        pinctrl-0 = <&pwm_ao_a_pins>;
        non-removable;
        disable-wp;
 
+       /* WiFi firmware requires power to be kept while in suspend */
+       keep-power-in-suspend;
+
        mmc-pwrseq = <&sdio_pwrseq>;
 
        vmmc-supply = <&vddao_3v3>;
        vqmmc-supply = <&emmc_1v8>;
 };
 
+&tdmif_a {
+       pinctrl-0 = <&tdm_a_dout0_pins>, <&tdm_a_fs_pins>, <&tdm_a_sclk_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       assigned-clocks = <&clkc_audio AUD_CLKID_TDM_SCLK_PAD0>,
+                         <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD0>;
+       assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+                                <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+       assigned-clock-rates = <0>, <0>;
+};
+
+&tdmif_b {
+       status = "okay";
+};
+
+&tdmin_a {
+       status = "okay";
+};
+
+&tdmin_b {
+       status = "okay";
+};
+
+&tdmout_a {
+       status = "okay";
+};
+
+&tdmout_b {
+       status = "okay";
+};
+
+&toddr_a {
+       status = "okay";
+};
+
+&toddr_b {
+       status = "okay";
+};
+
+&toddr_c {
+       status = "okay";
+};
+
+&tohdmitx {
+       status = "okay";
+};
+
 &uart_A {
        status = "okay";
        pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
index 256ea03..7894a54 100644 (file)
@@ -5,11 +5,47 @@
  */
 
 #include "meson-g12-common.dtsi"
+#include <dt-bindings/clock/axg-audio-clkc.h>
 #include <dt-bindings/power/meson-sm1-power.h>
+#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+#include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h>
 
 / {
        compatible = "amlogic,sm1";
 
+       tdmif_a: audio-controller-0 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_A";
+               clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_b: audio-controller-1 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_B";
+               clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_c: audio-controller-2 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_C";
+               clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
        cpus {
                #address-cells = <0x2>;
                #size-cells = <0x0>;
        };
 };
 
+&apb {
+       audio: bus@60000 {
+               compatible = "simple-bus";
+               reg = <0x0 0x60000 0x0 0x1000>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges = <0x0 0x0 0x0 0x60000 0x0 0x1000>;
+
+               clkc_audio: clock-controller@0 {
+                       status = "disabled";
+                       compatible = "amlogic,sm1-audio-clkc";
+                       reg = <0x0 0x0 0x0 0xb4>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+
+                       clocks = <&clkc CLKID_AUDIO>,
+                                <&clkc CLKID_MPLL0>,
+                                <&clkc CLKID_MPLL1>,
+                                <&clkc CLKID_MPLL2>,
+                                <&clkc CLKID_MPLL3>,
+                                <&clkc CLKID_HIFI_PLL>,
+                                <&clkc CLKID_FCLK_DIV3>,
+                                <&clkc CLKID_FCLK_DIV4>,
+                                <&clkc CLKID_FCLK_DIV5>;
+                       clock-names = "pclk",
+                                     "mst_in0",
+                                     "mst_in1",
+                                     "mst_in2",
+                                     "mst_in3",
+                                     "mst_in4",
+                                     "mst_in5",
+                                     "mst_in6",
+                                     "mst_in7";
+
+                       resets = <&reset RESET_AUDIO>;
+               };
+
+               toddr_a: audio-controller@100 {
+                       compatible = "amlogic,sm1-toddr",
+                                    "amlogic,axg-toddr";
+                       reg = <0x0 0x100 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "TODDR_A";
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
+                       resets = <&arb AXG_ARB_TODDR_A>,
+                                <&clkc_audio AUD_RESET_TODDR_A>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               toddr_b: audio-controller@140 {
+                       compatible = "amlogic,sm1-toddr",
+                                    "amlogic,axg-toddr";
+                       reg = <0x0 0x140 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "TODDR_B";
+                       interrupts = <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
+                       resets = <&arb AXG_ARB_TODDR_B>,
+                                <&clkc_audio AUD_RESET_TODDR_B>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               toddr_c: audio-controller@180 {
+                       compatible = "amlogic,sm1-toddr",
+                                    "amlogic,axg-toddr";
+                       reg = <0x0 0x180 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "TODDR_C";
+                       interrupts = <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
+                       resets = <&arb AXG_ARB_TODDR_C>,
+                                <&clkc_audio AUD_RESET_TODDR_C>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               frddr_a: audio-controller@1c0 {
+                       compatible = "amlogic,sm1-frddr",
+                                    "amlogic,axg-frddr";
+                       reg = <0x0 0x1c0 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "FRDDR_A";
+                       interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
+                       resets = <&arb AXG_ARB_FRDDR_A>,
+                                <&clkc_audio AUD_RESET_FRDDR_A>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               frddr_b: audio-controller@200 {
+                       compatible = "amlogic,sm1-frddr",
+                                    "amlogic,axg-frddr";
+                       reg = <0x0 0x200 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "FRDDR_B";
+                       interrupts = <GIC_SPI 153 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
+                       resets = <&arb AXG_ARB_FRDDR_B>,
+                                <&clkc_audio AUD_RESET_FRDDR_B>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               frddr_c: audio-controller@240 {
+                       compatible = "amlogic,sm1-frddr",
+                                    "amlogic,axg-frddr";
+                       reg = <0x0 0x240 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "FRDDR_C";
+                       interrupts = <GIC_SPI 154 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
+                       resets = <&arb AXG_ARB_FRDDR_C>,
+                                <&clkc_audio AUD_RESET_FRDDR_C>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               arb: reset-controller@280 {
+                       status = "disabled";
+                       compatible = "amlogic,meson-sm1-audio-arb";
+                       reg = <0x0 0x280 0x0 0x4>;
+                       #reset-cells = <1>;
+                       clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
+               };
+
+               tdmin_a: audio-controller@300 {
+                       compatible = "amlogic,sm1-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x300 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_A";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_A>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmin_b: audio-controller@340 {
+                       compatible = "amlogic,sm1-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x340 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_B";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_B>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmin_c: audio-controller@380 {
+                       compatible = "amlogic,sm1-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x380 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_C";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_C>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmin_lb: audio-controller@3c0 {
+                       compatible = "amlogic,sm1-tdmin",
+                                    "amlogic,axg-tdmin";
+                       reg = <0x0 0x3c0 0x0 0x40>;
+                       sound-name-prefix = "TDMIN_LB";
+                       resets = <&clkc_audio AUD_RESET_TDMIN_LB>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmout_a: audio-controller@500 {
+                       compatible = "amlogic,sm1-tdmout";
+                       reg = <0x0 0x500 0x0 0x40>;
+                       sound-name-prefix = "TDMOUT_A";
+                       resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmout_b: audio-controller@540 {
+                       compatible = "amlogic,sm1-tdmout";
+                       reg = <0x0 0x540 0x0 0x40>;
+                       sound-name-prefix = "TDMOUT_B";
+                       resets = <&clkc_audio AUD_RESET_TDMOUT_B>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tdmout_c: audio-controller@580 {
+                       compatible = "amlogic,sm1-tdmout";
+                       reg = <0x0 0x580 0x0 0x40>;
+                       sound-name-prefix = "TDMOUT_C";
+                       resets = <&clkc_audio AUD_RESET_TDMOUT_C>;
+                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
+                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
+                       clock-names = "pclk", "sclk", "sclk_sel",
+                                     "lrclk", "lrclk_sel";
+                       status = "disabled";
+               };
+
+               tohdmitx: audio-controller@744 {
+                       compatible = "amlogic,sm1-tohdmitx",
+                                    "amlogic,g12a-tohdmitx";
+                       reg = <0x0 0x744 0x0 0x4>;
+                       #sound-dai-cells = <1>;
+                       sound-name-prefix = "TOHDMITX";
+                       resets = <&clkc_audio AUD_RESET_TOHDMITX>;
+                       status = "disabled";
+               };
+
+               toddr_d: audio-controller@840 {
+                       compatible = "amlogic,sm1-toddr",
+                                    "amlogic,axg-toddr";
+                       reg = <0x0 0x840 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "TODDR_D";
+                       interrupts = <GIC_SPI 49 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_TODDR_D>;
+                       resets = <&arb AXG_ARB_TODDR_D>,
+                                <&clkc_audio AUD_RESET_TODDR_D>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+
+               frddr_d: audio-controller@880 {
+                        compatible = "amlogic,sm1-frddr",
+                                     "amlogic,axg-frddr";
+                       reg = <0x0 0x880 0x0 0x2c>;
+                       #sound-dai-cells = <0>;
+                       sound-name-prefix = "FRDDR_D";
+                       interrupts = <GIC_SPI 50 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkc_audio AUD_CLKID_FRDDR_D>;
+                       resets = <&arb AXG_ARB_FRDDR_D>,
+                                <&clkc_audio AUD_RESET_FRDDR_D>;
+                       reset-names = "arb", "rst";
+                       status = "disabled";
+               };
+       };
+
+       pdm: audio-controller@61000 {
+               compatible = "amlogic,sm1-pdm",
+                            "amlogic,axg-pdm";
+               reg = <0x0 0x61000 0x0 0x34>;
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "PDM";
+               clocks = <&clkc_audio AUD_CLKID_PDM>,
+                        <&clkc_audio AUD_CLKID_PDM_DCLK>,
+                        <&clkc_audio AUD_CLKID_PDM_SYSCLK>;
+               clock-names = "pclk", "dclk", "sysclk";
+               status = "disabled";
+       };
+};
+
 &cecb_AO {
        compatible = "amlogic,meson-sm1-ao-cec";
 };
        power-domains = <&pwrc PWRC_SM1_ETH_ID>;
 };
 
+&gpio_intc {
+       compatible = "amlogic,meson-sm1-gpio-intc",
+                    "amlogic,meson-gpio-intc";
+};
+
 &pcie {
        power-domains = <&pwrc PWRC_SM1_PCIE_ID>;
 };
        compatible = "amlogic,meson-sm1-pwrc";
 };
 
+&simplefb_cvbs {
+       power-domains = <&pwrc PWRC_SM1_VPU_ID>;
+};
+
+&simplefb_hdmi {
+       power-domains = <&pwrc PWRC_SM1_VPU_ID>;
+};
+
 &vpu {
        power-domains = <&pwrc PWRC_SM1_VPU_ID>;
 };
index 26a039a..1f3c80a 100644 (file)
@@ -6,7 +6,6 @@
        /*
         *  Devices shared by all Juno boards
         */
-       dma-ranges = <0 0 0 0 0x100 0>;
 
        memtimer: timer@2a810000 {
                compatible = "arm,armv7-timer-mem";
                clock-names = "apb_pclk";
        };
 
+       smmu_gpu: iommu@2b400000 {
+               compatible = "arm,mmu-400", "arm,smmu-v1";
+               reg = <0x0 0x2b400000 0x0 0x10000>;
+               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               #global-interrupts = <1>;
+               power-domains = <&scpi_devpd 1>;
+               dma-coherent;
+               status = "disabled";
+       };
+
        smmu_pcie: iommu@2b500000 {
                compatible = "arm,mmu-401", "arm,smmu-v1";
                reg = <0x0 0x2b500000 0x0 0x10000>;
                };
        };
 
+       gpu: gpu@2d000000 {
+               compatible = "arm,juno-mali", "arm,mali-t624";
+               reg = <0 0x2d000000 0 0x10000>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "gpu", "job", "mmu";
+               clocks = <&scpi_dvfs 2>;
+               power-domains = <&scpi_devpd 1>;
+               dma-coherent;
+               /* The SMMU is only really of interest to bare-metal hypervisors */
+               /* iommus = <&smmu_gpu 0>; */
+               status = "disabled";
+       };
+
        sram: sram@2e000000 {
                compatible = "arm,juno-sram-ns", "mmio-sram";
                reg = <0x0 0x2e000000 0x0 0x8000>;
index e5e265d..2870b5e 100644 (file)
@@ -8,10 +8,10 @@
  */
 / {
        /* SoC fixed clocks */
-       soc_uartclk: refclk7273800hz {
+       soc_uartclk: refclk7372800hz {
                compatible = "fixed-clock";
                #clock-cells = <0>;
-               clock-frequency = <7273800>;
+               clock-frequency = <7372800>;
                clock-output-names = "juno:uartclk";
        };
 
index d1d31cc..cb7de8d 100644 (file)
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
-dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-a-plus.dtb \
+dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb \
+                             bcm2837-rpi-3-a-plus.dtb \
                              bcm2837-rpi-3-b.dtb \
                              bcm2837-rpi-3-b-plus.dtb \
                              bcm2837-rpi-cm3-io3.dtb
diff --git a/arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts
new file mode 100644 (file)
index 0000000..d24c536
--- /dev/null
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "arm/bcm2711-rpi-4-b.dts"
index a76f620..6721966 100644 (file)
@@ -18,8 +18,8 @@
 
 / {
        compatible = "samsung,exynos5433";
-       #address-cells = <1>;
-       #size-cells = <1>;
+       #address-cells = <2>;
+       #size-cells = <2>;
 
        interrupt-parent = <&gic>;
 
                };
        };
 
-       gpu: gpu@14ac0000 {
-               compatible = "samsung,exynos5433-mali", "arm,mali-t760";
-               reg = <0x14ac0000 0x5000>;
-               interrupts = <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-names = "job", "mmu", "gpu";
-               clocks = <&cmu_g3d CLK_ACLK_G3D>;
-               clock-names = "core";
-               power-domains = <&pd_g3d>;
-               operating-points-v2 = <&gpu_opp_table>;
-               status = "disabled";
-
-               gpu_opp_table: opp_table {
-                       compatible = "operating-points-v2";
-
-                       opp-160000000 {
-                               opp-hz = /bits/ 64 <160000000>;
-                               opp-microvolt = <1000000>;
-                       };
-                       opp-267000000 {
-                               opp-hz = /bits/ 64 <267000000>;
-                               opp-microvolt = <1000000>;
-                       };
-                       opp-350000000 {
-                               opp-hz = /bits/ 64 <350000000>;
-                               opp-microvolt = <1025000>;
-                       };
-                       opp-420000000 {
-                               opp-hz = /bits/ 64 <420000000>;
-                               opp-microvolt = <1025000>;
-                       };
-                       opp-500000000 {
-                               opp-hz = /bits/ 64 <500000000>;
-                               opp-microvolt = <1075000>;
-                       };
-                       opp-550000000 {
-                               opp-hz = /bits/ 64 <550000000>;
-                               opp-microvolt = <1125000>;
-                       };
-                       opp-600000000 {
-                               opp-hz = /bits/ 64 <600000000>;
-                               opp-microvolt = <1150000>;
-                       };
-                       opp-700000000 {
-                               opp-hz = /bits/ 64 <700000000>;
-                               opp-microvolt = <1150000>;
-                       };
-               };
-       };
-
        psci {
                compatible = "arm,psci";
                method = "smc";
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
-               ranges;
+               ranges = <0x0 0x0 0x0 0x18000000>;
 
                chipid@10000000 {
                        compatible = "samsung,exynos4210-chipid";
                        status = "disabled";
                };
 
-               mct@101c0000 {
+               timer@101c0000 {
                        compatible = "samsung,exynos4210-mct";
                        reg = <0x101c0000 0x800>;
                        interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
                        power-domains = <&pd_gscl>;
                };
 
+               gpu: gpu@14ac0000 {
+                       compatible = "samsung,exynos5433-mali", "arm,mali-t760";
+                       reg = <0x14ac0000 0x5000>;
+                       interrupts = <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "job", "mmu", "gpu";
+                       clocks = <&cmu_g3d CLK_ACLK_G3D>;
+                       clock-names = "core";
+                       power-domains = <&pd_g3d>;
+                       operating-points-v2 = <&gpu_opp_table>;
+                       status = "disabled";
+
+                       gpu_opp_table: opp_table {
+                               compatible = "operating-points-v2";
+
+                               opp-160000000 {
+                                       opp-hz = /bits/ 64 <160000000>;
+                                       opp-microvolt = <1000000>;
+                               };
+                               opp-267000000 {
+                                       opp-hz = /bits/ 64 <267000000>;
+                                       opp-microvolt = <1000000>;
+                               };
+                               opp-350000000 {
+                                       opp-hz = /bits/ 64 <350000000>;
+                                       opp-microvolt = <1025000>;
+                               };
+                               opp-420000000 {
+                                       opp-hz = /bits/ 64 <420000000>;
+                                       opp-microvolt = <1025000>;
+                               };
+                               opp-500000000 {
+                                       opp-hz = /bits/ 64 <500000000>;
+                                       opp-microvolt = <1075000>;
+                               };
+                               opp-550000000 {
+                                       opp-hz = /bits/ 64 <550000000>;
+                                       opp-microvolt = <1125000>;
+                               };
+                               opp-600000000 {
+                                       opp-hz = /bits/ 64 <600000000>;
+                                       opp-microvolt = <1150000>;
+                               };
+                               opp-700000000 {
+                                       opp-hz = /bits/ 64 <700000000>;
+                                       opp-microvolt = <1150000>;
+                               };
+                       };
+               };
+
                scaler_0: scaler@15000000 {
                        compatible = "samsung,exynos5433-scaler";
                        reg = <0x15000000 0x1294>;
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x13a00000 0x1000>;
                        interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_disp CLK_PCLK_SMMU_DECON0X>,
-                               <&cmu_disp CLK_ACLK_SMMU_DECON0X>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_disp CLK_ACLK_SMMU_DECON0X>,
+                               <&cmu_disp CLK_PCLK_SMMU_DECON0X>;
                        power-domains = <&pd_disp>;
                        #iommu-cells = <0>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x13a10000 0x1000>;
                        interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_disp CLK_PCLK_SMMU_DECON1X>,
-                               <&cmu_disp CLK_ACLK_SMMU_DECON1X>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_disp CLK_ACLK_SMMU_DECON1X>,
+                               <&cmu_disp CLK_PCLK_SMMU_DECON1X>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_disp>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x13a20000 0x1000>;
                        interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_disp CLK_PCLK_SMMU_TV0X>,
-                               <&cmu_disp CLK_ACLK_SMMU_TV0X>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_disp CLK_ACLK_SMMU_TV0X>,
+                               <&cmu_disp CLK_PCLK_SMMU_TV0X>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_disp>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x13a30000 0x1000>;
                        interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_disp CLK_PCLK_SMMU_TV1X>,
-                               <&cmu_disp CLK_ACLK_SMMU_TV1X>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_disp CLK_ACLK_SMMU_TV1X>,
+                               <&cmu_disp CLK_PCLK_SMMU_TV1X>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_disp>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x15040000 0x1000>;
                        interrupts = <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_mscl CLK_PCLK_SMMU_M2MSCALER0>,
-                                <&cmu_mscl CLK_ACLK_SMMU_M2MSCALER0>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_mscl CLK_ACLK_SMMU_M2MSCALER0>,
+                               <&cmu_mscl CLK_PCLK_SMMU_M2MSCALER0>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_mscl>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x15050000 0x1000>;
                        interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_mscl CLK_PCLK_SMMU_M2MSCALER1>,
-                                <&cmu_mscl CLK_ACLK_SMMU_M2MSCALER1>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_mscl CLK_ACLK_SMMU_M2MSCALER1>,
+                               <&cmu_mscl CLK_PCLK_SMMU_M2MSCALER1>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_mscl>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x15060000 0x1000>;
                        interrupts = <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_mscl CLK_PCLK_SMMU_JPEG>,
-                                <&cmu_mscl CLK_ACLK_SMMU_JPEG>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_mscl CLK_ACLK_SMMU_JPEG>,
+                               <&cmu_mscl CLK_PCLK_SMMU_JPEG>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_mscl>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x15200000 0x1000>;
                        interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_mfc CLK_PCLK_SMMU_MFC_0>,
-                                <&cmu_mfc CLK_ACLK_SMMU_MFC_0>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_mfc CLK_ACLK_SMMU_MFC_0>,
+                               <&cmu_mfc CLK_PCLK_SMMU_MFC_0>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_mfc>;
                };
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x15210000 0x1000>;
                        interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "pclk", "aclk";
-                       clocks = <&cmu_mfc CLK_PCLK_SMMU_MFC_1>,
-                                <&cmu_mfc CLK_ACLK_SMMU_MFC_1>;
+                       clock-names = "aclk", "pclk";
+                       clocks = <&cmu_mfc CLK_ACLK_SMMU_MFC_1>,
+                               <&cmu_mfc CLK_PCLK_SMMU_MFC_1>;
                        #iommu-cells = <0>;
                        power-domains = <&pd_mfc>;
                };
                i2s1: i2s@14d60000 {
                        compatible = "samsung,exynos7-i2s";
                        reg = <0x14d60000 0x100>;
-                       dmas = <&pdma0 31 &pdma0 30>;
+                       dmas = <&pdma0 31>, <&pdma0 30>;
                        dma-names = "tx", "rx";
                        interrupts = <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cmu_peric CLK_PCLK_I2S1>,
                        i2s0: i2s@11440000 {
                                compatible = "samsung,exynos7-i2s";
                                reg = <0x11440000 0x100>;
-                               dmas = <&adma 0 &adma 2>;
+                               dmas = <&adma 0>, <&adma 2>;
                                dma-names = "tx", "rx";
                                interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
                                #address-cells = <1>;
index bcb9d8c..3a00ef0 100644 (file)
@@ -12,8 +12,8 @@
 / {
        compatible = "samsung,exynos7";
        interrupt-parent = <&gic>;
-       #address-cells = <1>;
-       #size-cells = <1>;
+       #address-cells = <2>;
+       #size-cells = <2>;
 
        aliases {
                pinctrl0 = &pinctrl_alive;
                };
        };
 
-       gpu: gpu@14ac0000 {
-               compatible = "samsung,exynos5433-mali", "arm,mali-t760";
-               reg = <0x14ac0000 0x5000>;
-               interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-names = "job", "mmu", "gpu";
-               status = "disabled";
-               /* TODO: operating points for DVFS, cooling device */
-       };
-
        psci {
                compatible = "arm,psci-0.2";
                method = "smc";
@@ -98,7 +87,7 @@
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
-               ranges;
+               ranges = <0 0 0 0x18000000>;
 
                chipid@10000000 {
                        compatible = "samsung,exynos4210-chipid";
                        status = "disabled";
                };
 
+               gpu: gpu@14ac0000 {
+                       compatible = "samsung,exynos5433-mali", "arm,mali-t760";
+                       reg = <0x14ac0000 0x5000>;
+                       interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "job", "mmu", "gpu";
+                       status = "disabled";
+                       /* TODO: operating points for DVFS, cooling device */
+               };
+
                mmc_0: mmc@15740000 {
                        compatible = "samsung,exynos7-dw-mshc-smu";
                        interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
index 93fce8f..38e344a 100644 (file)
@@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mn-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb
@@ -31,4 +32,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mq-pico-pi.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-rmb3.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-zest.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-ai_ml.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
+
+dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
index 078a501..5b9d4b3 100644 (file)
        };
 
        fpga@66 {
-               #address-cells = <1>;
-               #size-cells = <0>;
                compatible = "fsl,ls1028aqds-fpga", "fsl,fpga-qixis-i2c",
                             "simple-mfd";
                reg = <0x66>;
index 1a69221..9720a19 100644 (file)
 &sata {
        status = "okay";
 };
+
+&usb1 {
+       dr_mode = "otg";
+};
index 72b9a75..13a3cbe 100644 (file)
        dpclk: clock-controller@f1f0000 {
                compatible = "fsl,ls1028a-plldig";
                reg = <0x0 0xf1f0000 0x0 0xffff>;
-               #clock-cells = <1>;
-               clocks = <&osc_27m>;
-       };
-
-       aclk: clock-axi {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <650000000>;
-               clock-output-names= "aclk";
-       };
-
-       pclk: clock-apb {
-               compatible = "fixed-clock";
                #clock-cells = <0>;
-               clock-frequency = <650000000>;
-               clock-output-names= "pclk";
+               clocks = <&osc_27m>;
        };
 
        reboot {
                compatible ="syscon-reboot";
-               regmap = <&dcfg>;
+               regmap = <&rst>;
                offset = <0xb0>;
                mask = <0x02>;
        };
                };
        };
 
+       thermal-zones {
+               core-cluster {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <5000>;
+                       thermal-sensors = <&tmu 0>;
+
+                       trips {
+                               core_cluster_alert: core-cluster-alert {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               core_cluster_crit: core-cluster-crit {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&core_cluster_alert>;
+                                       cooling-device =
+                                               <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+       };
+
        soc: soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                        big-endian;
                };
 
+               rst: syscon@1e60000 {
+                       compatible = "syscon";
+                       reg = <0x0 0x1e60000 0x0 0x10000>;
+                       little-endian;
+               };
+
                scfg: syscon@1fc0000 {
                        compatible = "fsl,ls1028a-scfg", "syscon";
                        reg = <0x0 0x1fc0000 0x0 0x10000>;
                        status = "disabled";
                };
 
-               tmu: tmu@1f00000 {
+               tmu: tmu@1f80000 {
                        compatible = "fsl,qoriq-tmu";
                        reg = <0x0 0x1f80000 0x0 0x10000>;
                        interrupts = <0 23 0x4>;
                                               0x00010004 0x0000003d
                                               0x00010005 0x00000045
                                               0x00010006 0x0000004d
-                                              0x00010007 0x00000045
+                                              0x00010007 0x00000055
                                               0x00010008 0x0000005e
                                               0x00010009 0x00000066
                                               0x0001000a 0x0000006e
                        #thermal-sensor-cells = <1>;
                };
 
-               thermal-zones {
-                       core-cluster {
-                               polling-delay-passive = <1000>;
-                               polling-delay = <5000>;
-                               thermal-sensors = <&tmu 0>;
-
-                               trips {
-                                       core_cluster_alert: core-cluster-alert {
-                                               temperature = <85000>;
-                                               hysteresis = <2000>;
-                                               type = "passive";
-                                       };
-
-                                       core_cluster_crit: core-cluster-crit {
-                                               temperature = <95000>;
-                                               hysteresis = <2000>;
-                                               type = "critical";
-                                       };
-                               };
-
-                               cooling-maps {
-                                       map0 {
-                                               trip = <&core_cluster_alert>;
-                                               cooling-device =
-                                                       <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-                                                       <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
-                                       };
-                               };
-                       };
-               };
-
                pcie@1f0000000 { /* Integrated Endpoint Root Complex */
                        compatible = "pci-host-ecam-generic";
                        reg = <0x01 0xf0000000 0x0 0x100000>;
                interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
                             <0 223 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "DE", "SE";
-               clocks = <&dpclk 0>, <&aclk>, <&aclk>, <&pclk>;
+               clocks = <&dpclk>, <&clockgen 2 2>, <&clockgen 2 2>,
+                        <&clockgen 2 2>;
                clock-names = "pxlclk", "mclk", "aclk", "pclk";
                arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
                arm,malidp-arqos-value = <0xd000d000>;
index 6a6514d..0c742be 100644 (file)
        };
 };
 
+&usb1 {
+       dr_mode = "otg";
+};
+
 #include "fsl-ls1046-post.dtsi"
 
 &fman0 {
index 8e925df..90b1989 100644 (file)
@@ -95,5 +95,6 @@
 };
 
 &usb1 {
+       dr_mode = "otg";
        status = "okay";
 };
index b032f38..e883fe0 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
 
 /memreserve/ 0x80000000 0x00010000;
 
@@ -20,7 +21,7 @@
                #size-cells = <0>;
 
                // 8 clusters having 2 Cortex-A72 cores each
-               cpu@0 {
+               cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster0_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@1 {
+               cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster0_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@100 {
+               cpu100: cpu@100 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster1_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@101 {
+               cpu101: cpu@101 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster1_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@200 {
+               cpu200: cpu@200 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster2_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@201 {
+               cpu201: cpu@201 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster2_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@300 {
+               cpu300: cpu@300 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster3_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@301 {
+               cpu301: cpu@301 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster3_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@400 {
+               cpu400: cpu@400 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster4_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@401 {
+               cpu401: cpu@401 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster4_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@500 {
+               cpu500: cpu@500 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster5_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@501 {
+               cpu501: cpu@501 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster5_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@600 {
+               cpu600: cpu@600 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster6_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@601 {
+               cpu601: cpu@601 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster6_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@700 {
+               cpu700: cpu@700 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster7_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
-               cpu@701 {
+               cpu701: cpu@701 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72";
                        enable-method = "psci";
                        i-cache-sets = <192>;
                        next-level-cache = <&cluster7_l2>;
                        cpu-idle-states = <&cpu_pw15>;
+                       #cooling-cells = <2>;
                };
 
                cluster0_l2: l2-cache0 {
                clock-output-names = "sysclk";
        };
 
+       thermal-zones {
+               core_thermal1: core-thermal1 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <5000>;
+                       thermal-sensors = <&tmu 0>;
+
+                       trips {
+                               core_cluster_alert: core-cluster-alert {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               core_cluster_crit: core-cluster-crit {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&core_cluster_alert>;
+                                       cooling-device =
+                                               <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu200 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu201 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu300 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu301 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu400 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu401 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu500 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu501 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu600 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu601 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu700 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                               <&cpu701 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                        little-endian;
                };
 
+               tmu: tmu@1f80000 {
+                       compatible = "fsl,qoriq-tmu";
+                       reg = <0x0 0x1f80000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                       fsl,tmu-range = <0x800000e6 0x8001017d>;
+                       fsl,tmu-calibration =
+                               /* Calibration data group 1 */
+                               <0x00000000 0x00000035
+                               /* Calibration data group 2 */
+                               0x00010001 0x00000154>;
+                       little-endian;
+                       #thermal-sensor-cells = <1>;
+               };
+
                i2c0: i2c@2000000 {
                        compatible = "fsl,vf610-i2c";
                        #address-cells = <1>;
                        reg = <0x0 0x2140000 0x0 0x10000>;
                        interrupts = <0 28 0x4>; /* Level high type */
                        clocks = <&clockgen 4 1>;
+                       dma-coherent;
                        voltage-ranges = <1800 1800 3300 3300>;
                        sdhci,auto-cmd12;
                        little-endian;
                        reg = <0x0 0x2150000 0x0 0x10000>;
                        interrupts = <0 63 0x4>; /* Level high type */
                        clocks = <&clockgen 4 1>;
+                       dma-coherent;
                        voltage-ranges = <1800 1800 3300 3300>;
                        sdhci,auto-cmd12;
                        broken-cd;
index f7a15f3..28ab17a 100644 (file)
@@ -62,6 +62,8 @@
 
                cpudai: simple-audio-card,cpu {
                        sound-dai = <&sai3>;
+                       dai-tdm-slot-num = <2>;
+                       dai-tdm-slot-width = <32>;
                };
 
                simple-audio-card,codec {
        };
 };
 
-&sai3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_sai3>;
-       assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
-       assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
-       assigned-clock-rates = <24576000>;
-       status = "okay";
-};
-
-&snvs_pwrkey {
-       status = "okay";
-};
-
-&uart2 { /* console */
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2>;
-       status = "okay";
-};
-
-&usbotg1 {
-       dr_mode = "otg";
-       hnp-disable;
-       srp-disable;
-       adp-disable;
-       usb-role-switch;
-       status = "okay";
-
-       port {
-               usb1_drd_sw: endpoint {
-                       remote-endpoint = <&typec1_dr_sw>;
-               };
-       };
-};
-
-&usdhc2 {
-       pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
-       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
-       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
-       cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
-       bus-width = <4>;
-       vmmc-supply = <&reg_usdhc2_vmmc>;
-       status = "okay";
-};
-
-&usdhc3 {
-       pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc3>;
-       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
-       bus-width = <8>;
-       non-removable;
-       status = "okay";
-};
-
-&wdog1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_wdog>;
-       fsl,ext-reset-output;
-       status = "okay";
-};
-
 &i2c1 {
        clock-frequency = <400000>;
        pinctrl-names = "default";
        };
 };
 
+&i2c3 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       pca6416: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&sai3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sai3>;
+       assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
+       assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+       assigned-clock-rates = <24576000>;
+       status = "okay";
+};
+
+&snvs_pwrkey {
+       status = "okay";
+};
+
+&uart2 { /* console */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usbotg1 {
+       dr_mode = "otg";
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+       usb-role-switch;
+       status = "okay";
+
+       port {
+               usb1_drd_sw: endpoint {
+                       remote-endpoint = <&typec1_dr_sw>;
+               };
+       };
+};
+
+&usdhc2 {
+       assigned-clocks = <&clk IMX8MM_CLK_USDHC2>;
+       assigned-clock-rates = <200000000>;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       status = "okay";
+};
+
+&usdhc3 {
+       assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
+       assigned-clock-rates = <400000000>;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
 &iomuxc {
        pinctrl-names = "default";
 
                >;
        };
 
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL                  0x400001c3
+                       MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA                  0x400001c3
+               >;
+       };
+
        pinctrl_pmic: pmicirq {
                fsl,pins = <
                        MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3               0x41
index 23c8fad..6edbdfe 100644 (file)
@@ -12,7 +12,6 @@
 #include "imx8mm-pinfunc.h"
 
 / {
-       compatible = "fsl,imx8mm";
        interrupt-parent = <&gic>;
        #address-cells = <2>;
        #size-cells = <2>;
                        };
 
                        ocotp: ocotp-ctrl@30350000 {
-                               compatible = "fsl,imx8mm-ocotp", "fsl,imx7d-ocotp", "syscon";
+                               compatible = "fsl,imx8mm-ocotp", "syscon";
                                reg = <0x30350000 0x10000>;
                                clocks = <&clk IMX8MM_CLK_OCOTP_ROOT>;
                                /* For nvmem subnodes */
                                                <&clk IMX8MM_CLK_AUDIO_AHB>,
                                                <&clk IMX8MM_CLK_IPG_AUDIO_ROOT>,
                                                <&clk IMX8MM_SYS_PLL3>,
-                                               <&clk IMX8MM_VIDEO_PLL1>;
+                                               <&clk IMX8MM_VIDEO_PLL1>,
+                                               <&clk IMX8MM_AUDIO_PLL1>,
+                                               <&clk IMX8MM_AUDIO_PLL2>;
                                assigned-clock-parents = <&clk IMX8MM_SYS_PLL3_OUT>,
                                                         <&clk IMX8MM_SYS_PLL1_800M>;
                                assigned-clock-rates = <0>,
                                                        <400000000>,
                                                        <400000000>,
                                                        <750000000>,
-                                                       <594000000>;
+                                                       <594000000>,
+                                                       <393216000>,
+                                                       <361267200>;
                        };
 
                        src: reset-controller@30390000 {
                                         <&clk IMX8MM_CLK_NAND_USDHC_BUS>,
                                         <&clk IMX8MM_CLK_USDHC1_ROOT>;
                                clock-names = "ipg", "ahb", "per";
-                               assigned-clocks = <&clk IMX8MM_CLK_USDHC1>;
-                               assigned-clock-rates = <400000000>;
                                fsl,tuning-start-tap = <20>;
                                fsl,tuning-step= <2>;
                                bus-width = <4>;
                                         <&clk IMX8MM_CLK_NAND_USDHC_BUS>,
                                         <&clk IMX8MM_CLK_USDHC3_ROOT>;
                                clock-names = "ipg", "ahb", "per";
-                               assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
-                               assigned-clock-rates = <400000000>;
                                fsl,tuning-start-tap = <20>;
                                fsl,tuning-step= <2>;
                                bus-width = <4>;
index 11c705d..0719494 100644 (file)
 /dts-v1/;
 
 #include "imx8mn.dtsi"
+#include "imx8mn-evk.dtsi"
 
 / {
        model = "NXP i.MX8MNano DDR4 EVK board";
        compatible = "fsl,imx8mn-ddr4-evk", "fsl,imx8mn";
-
-       chosen {
-               stdout-path = &uart2;
-       };
-
-       reg_usdhc2_vmmc: regulator-usdhc2 {
-               compatible = "regulator-fixed";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
-               regulator-name = "VSD_3V3";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
 };
 
 &A53_0 {
        cpu-supply = <&buck2_reg>;
 };
 
-&iomuxc {
-       pinctrl-names = "default";
-
-       pinctrl_fec1: fec1grp {
-               fsl,pins = <
-                       MX8MN_IOMUXC_ENET_MDC_ENET1_MDC         0x3
-                       MX8MN_IOMUXC_ENET_MDIO_ENET1_MDIO       0x3
-                       MX8MN_IOMUXC_ENET_TD3_ENET1_RGMII_TD3   0x1f
-                       MX8MN_IOMUXC_ENET_TD2_ENET1_RGMII_TD2   0x1f
-                       MX8MN_IOMUXC_ENET_TD1_ENET1_RGMII_TD1   0x1f
-                       MX8MN_IOMUXC_ENET_TD0_ENET1_RGMII_TD0   0x1f
-                       MX8MN_IOMUXC_ENET_RD3_ENET1_RGMII_RD3   0x91
-                       MX8MN_IOMUXC_ENET_RD2_ENET1_RGMII_RD2   0x91
-                       MX8MN_IOMUXC_ENET_RD1_ENET1_RGMII_RD1   0x91
-                       MX8MN_IOMUXC_ENET_RD0_ENET1_RGMII_RD0   0x91
-                       MX8MN_IOMUXC_ENET_TXC_ENET1_RGMII_TXC   0x1f
-                       MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC   0x91
-                       MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
-                       MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1f
-                       MX8MN_IOMUXC_SAI2_RXC_GPIO4_IO22        0x19
-               >;
-       };
-
-       pinctrl_i2c1: i2c1grp {
-               fsl,pins = <
-                       MX8MN_IOMUXC_I2C1_SCL_I2C1_SCL          0x400001c3
-                       MX8MN_IOMUXC_I2C1_SDA_I2C1_SDA          0x400001c3
-               >;
-       };
-
-       pinctrl_pmic: pmicirq {
-               fsl,pins = <
-                       MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3       0x41
-               >;
-       };
-
-       pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc {
-               fsl,pins = <
-                       MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19     0x41
-               >;
-       };
-
-       pinctrl_uart2: uart2grp {
-               fsl,pins = <
-                       MX8MN_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
-                       MX8MN_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
-               >;
-       };
-
-       pinctrl_usdhc2_gpio: usdhc2grpgpio {
-               fsl,pins = <
-                       MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15      0x1c4
-               >;
-       };
-
-       pinctrl_usdhc2: usdhc2grp {
-               fsl,pins = <
-                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x190
-                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d0
-                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d0
-                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d0
-                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d0
-                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d0
-                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
-               >;
-       };
-
-       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
-               fsl,pins = <
-                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x194
-                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d4
-                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d4
-                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d4
-                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d4
-                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d4
-                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
-               >;
-       };
-
-       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
-               fsl,pins = <
-                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x196
-                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d6
-                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d6
-                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d6
-                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d6
-                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d6
-                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
-               >;
-       };
-
-       pinctrl_usdhc3: usdhc3grp {
-               fsl,pins = <
-                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000190
-                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d0
-                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d0
-                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d0
-                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d0
-                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d0
-                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d0
-                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d0
-                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d0
-                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d0
-                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x190
-               >;
-       };
-
-       pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
-               fsl,pins = <
-                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000194
-                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d4
-                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d4
-                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d4
-                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d4
-                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d4
-                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d4
-                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d4
-                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d4
-                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d4
-                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x194
-               >;
-       };
-
-       pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
-               fsl,pins = <
-                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000196
-                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d6
-                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d6
-                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d6
-                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d6
-                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d6
-                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d6
-                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d6
-                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d6
-                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d6
-                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x196
-               >;
-       };
-
-       pinctrl_wdog: wdoggrp {
-               fsl,pins = <
-                       MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B            0xc6
-               >;
-       };
-};
-
-&fec1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec1>;
-       phy-mode = "rgmii-id";
-       phy-handle = <&ethphy0>;
-       fsl,magic-packet;
-       status = "okay";
-
-       mdio {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               ethphy0: ethernet-phy@0 {
-                       compatible = "ethernet-phy-ieee802.3-c22";
-                       reg = <0>;
-                       at803x,led-act-blind-workaround;
-                       at803x,eee-disabled;
-                       at803x,vddio-1p8v;
-               };
-       };
-};
-
 &i2c1 {
-       clock-frequency = <400000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1>;
-       status = "okay";
-
        pmic@4b {
                compatible = "rohm,bd71847";
                reg = <0x4b>;
        };
 };
 
-&snvs_pwrkey {
-       status = "okay";
-};
-
-&uart2 { /* console */
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2>;
-       status = "okay";
-};
-
-&usdhc2 {
-       pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
-       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
-       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
-       cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
-       bus-width = <4>;
-       vmmc-supply = <&reg_usdhc2_vmmc>;
-       status = "okay";
-};
-
-&usdhc3 {
-       pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc3>;
-       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
-       bus-width = <8>;
-       non-removable;
-       status = "okay";
-};
-
-&wdog1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_wdog>;
-       fsl,ext-reset-output;
-       status = "okay";
+&iomuxc {
+       pinctrl_pmic: pmicirq {
+               fsl,pins = <
+                       MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3       0x41
+               >;
+       };
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts
new file mode 100644 (file)
index 0000000..61f3519
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2019 NXP
+ */
+
+/dts-v1/;
+
+#include "imx8mn.dtsi"
+#include "imx8mn-evk.dtsi"
+
+/ {
+       model = "NXP i.MX8MNano EVK board";
+       compatible = "fsl,imx8mn-evk", "fsl,imx8mn";
+};
+
+&A53_0 {
+       /delete-property/operating-points-v2;
+};
+
+&A53_1 {
+       /delete-property/operating-points-v2;
+};
+
+&A53_2 {
+       /delete-property/operating-points-v2;
+};
+
+&A53_3 {
+       /delete-property/operating-points-v2;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
new file mode 100644 (file)
index 0000000..2a74330
--- /dev/null
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2019 NXP
+ */
+
+#include "imx8mn.dtsi"
+
+/ {
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_led>;
+
+               status {
+                       label = "yellow:status";
+                       gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
+                       default-state = "on";
+               };
+       };
+
+       reg_usdhc2_vmmc: regulator-usdhc2 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+               regulator-name = "VSD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethphy0>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+};
+
+&snvs_pwrkey {
+       status = "okay";
+};
+
+&uart2 { /* console */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usdhc2 {
+       assigned-clocks = <&clk IMX8MN_CLK_USDHC2>;
+       assigned-clock-rates = <200000000>;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       status = "okay";
+};
+
+&usdhc3 {
+       assigned-clocks = <&clk IMX8MN_CLK_USDHC3_ROOT>;
+       assigned-clock-rates = <400000000>;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_ENET_MDC_ENET1_MDC         0x3
+                       MX8MN_IOMUXC_ENET_MDIO_ENET1_MDIO       0x3
+                       MX8MN_IOMUXC_ENET_TD3_ENET1_RGMII_TD3   0x1f
+                       MX8MN_IOMUXC_ENET_TD2_ENET1_RGMII_TD2   0x1f
+                       MX8MN_IOMUXC_ENET_TD1_ENET1_RGMII_TD1   0x1f
+                       MX8MN_IOMUXC_ENET_TD0_ENET1_RGMII_TD0   0x1f
+                       MX8MN_IOMUXC_ENET_RD3_ENET1_RGMII_RD3   0x91
+                       MX8MN_IOMUXC_ENET_RD2_ENET1_RGMII_RD2   0x91
+                       MX8MN_IOMUXC_ENET_RD1_ENET1_RGMII_RD1   0x91
+                       MX8MN_IOMUXC_ENET_RD0_ENET1_RGMII_RD0   0x91
+                       MX8MN_IOMUXC_ENET_TXC_ENET1_RGMII_TXC   0x1f
+                       MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC   0x91
+                       MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
+                       MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1f
+                       MX8MN_IOMUXC_SAI2_RXC_GPIO4_IO22        0x19
+               >;
+       };
+
+       pinctrl_gpio_led: gpioledgrp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_NAND_READY_B_GPIO3_IO16    0x19
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_I2C1_SCL_I2C1_SCL          0x400001c3
+                       MX8MN_IOMUXC_I2C1_SDA_I2C1_SDA          0x400001c3
+               >;
+       };
+
+       pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19     0x41
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+                       MX8MN_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+               >;
+       };
+
+       pinctrl_usdhc2_gpio: usdhc2grpgpio {
+               fsl,pins = <
+                       MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15      0x1c4
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x190
+                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d0
+                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d0
+                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d0
+                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d0
+                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d0
+                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x194
+                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d4
+                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d4
+                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d4
+                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d4
+                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d4
+                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x196
+                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d6
+                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d6
+                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d6
+                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d6
+                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d6
+                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000190
+                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d0
+                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d0
+                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d0
+                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d0
+                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d0
+                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d0
+                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d0
+                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d0
+                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d0
+                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x190
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000194
+                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d4
+                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d4
+                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d4
+                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d4
+                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d4
+                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d4
+                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d4
+                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d4
+                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d4
+                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x194
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000196
+                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d6
+                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d6
+                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d6
+                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d6
+                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d6
+                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d6
+                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d6
+                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d6
+                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d6
+                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x196
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B            0xc6
+               >;
+       };
+};
index 43c4db3..e916250 100644 (file)
@@ -11,7 +11,6 @@
 #include "imx8mn-pinfunc.h"
 
 / {
-       compatible = "fsl,imx8mn";
        interrupt-parent = <&gic>;
        #address-cells = <2>;
        #size-cells = <2>;
                #address-cells = <1>;
                #size-cells = <0>;
 
+               idle-states {
+                       entry-method = "psci";
+
+                       cpu_pd_wait: cpu-pd-wait {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010033>;
+                               local-timer-stop;
+                               entry-latency-us = <1000>;
+                               exit-latency-us = <700>;
+                               min-residency-us = <2700>;
+                       };
+               };
+
                A53_0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a53";
@@ -54,6 +66,7 @@
                        operating-points-v2 = <&a53_opp_table>;
                        nvmem-cells = <&cpu_speed_grade>;
                        nvmem-cell-names = "speed_grade";
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_1: cpu@1 {
@@ -65,6 +78,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        operating-points-v2 = <&a53_opp_table>;
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_2: cpu@2 {
@@ -76,6 +90,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        operating-points-v2 = <&a53_opp_table>;
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_3: cpu@3 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        operating-points-v2 = <&a53_opp_table>;
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_L2: l2-cache0 {
                        };
 
                        ocotp: ocotp-ctrl@30350000 {
-                               compatible = "fsl,imx8mn-ocotp", "fsl,imx7d-ocotp", "syscon";
+                               compatible = "fsl,imx8mn-ocotp", "fsl,imx8mm-ocotp", "syscon";
                                reg = <0x30350000 0x10000>;
                                clocks = <&clk IMX8MN_CLK_OCOTP_ROOT>;
                                #address-cells = <1>;
                        };
 
                        src: reset-controller@30390000 {
-                               compatible = "fsl,imx8mn-src", "syscon";
+                               compatible = "fsl,imx8mn-src", "fsl,imx8mq-src", "syscon";
                                reg = <0x30390000 0x10000>;
                                interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
                                #reset-cells = <1>;
                                #pwm-cells = <2>;
                                status = "disabled";
                        };
+
+                       system_counter: timer@306a0000 {
+                               compatible = "nxp,sysctr-timer";
+                               reg = <0x306a0000 0x20000>;
+                               interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&osc_24m>;
+                               clock-names = "per";
+                       };
                };
 
                aips3: bus@30800000 {
                                         <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
                                         <&clk IMX8MN_CLK_USDHC1_ROOT>;
                                clock-names = "ipg", "ahb", "per";
-                               assigned-clocks = <&clk IMX8MN_CLK_USDHC1>;
-                               assigned-clock-rates = <400000000>;
                                fsl,tuning-start-tap = <20>;
                                fsl,tuning-step= <2>;
                                bus-width = <4>;
                                         <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
                                         <&clk IMX8MN_CLK_USDHC3_ROOT>;
                                clock-names = "ipg", "ahb", "per";
-                               assigned-clocks = <&clk IMX8MN_CLK_USDHC3_ROOT>;
-                               assigned-clock-rates = <400000000>;
                                fsl,tuning-start-tap = <20>;
                                fsl,tuning-step= <2>;
                                bus-width = <4>;
                        interrupt-controller;
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                };
+
+               ddr-pmu@3d800000 {
+                       compatible = "fsl,imx8mn-ddr-pmu", "fsl,imx8m-ddr-pmu";
+                       reg = <0x3d800000 0x400000>;
+                       interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+               };
        };
 
        usbphynop1: usbphynop1 {
index 0595812..c366859 100644 (file)
                gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
                states = <1000000 0x0
                          900000 0x1>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       ir-receiver {
+               compatible = "gpio-ir-receiver";
+               gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ir>;
        };
 
        wm8524: audio-codec {
        };
 };
 
-&sai2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_sai2>;
-       assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1_BYPASS>, <&clk IMX8MQ_CLK_SAI2>;
-       assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1>, <&clk IMX8MQ_AUDIO_PLL1_OUT>;
-       assigned-clock-rates = <0>, <24576000>;
-       status = "okay";
-};
-
 &gpio5 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_wifi_reset>;
        power-supply = <&sw1a_reg>;
 };
 
+&qspi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi>;
+       status = "okay";
+
+       n25q256a: flash@0 {
+               reg = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "micron,n25q256a", "jedec,spi-nor";
+               spi-max-frequency = <29000000>;
+       };
+};
+
+&sai2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sai2>;
+       assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1_BYPASS>, <&clk IMX8MQ_CLK_SAI2>;
+       assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1>, <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+       assigned-clock-rates = <0>, <24576000>;
+       status = "okay";
+};
+
 &snvs_pwrkey {
        status = "okay";
 };
        status = "okay";
 };
 
-&qspi0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_qspi>;
-       status = "okay";
-
-       n25q256a: flash@0 {
-               reg = <0>;
-               #address-cells = <1>;
-               #size-cells = <1>;
-               compatible = "micron,n25q256a", "jedec,spi-nor";
-               spi-max-frequency = <29000000>;
-       };
-};
-
 &usdhc1 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
+       assigned-clock-rates = <400000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc1>;
        pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
 };
 
 &usdhc2 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC2>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2>;
        pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
                >;
        };
 
+       pinctrl_ir: irgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12              0x4f
+               >;
+       };
+
        pinctrl_pcie0: pcie0grp {
                fsl,pins = <
                        MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B            0x76
index f52e872..b8cb20c 100644 (file)
 };
 
 &usdhc2 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC2>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
        pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
index 683a110..2a759df 100644 (file)
 };
 
 &usdhc1 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
+       assigned-clock-rates = <400000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc1>;
        pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
 };
 
 &usdhc2 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC2>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2>;
        pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
index c832bf0..81d2692 100644 (file)
 };
 
 &usdhc1 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
+       assigned-clock-rates = <400000000>;
        bus-width = <8>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc1>;
index 8a4aee2..59da96b 100644 (file)
 };
 
 &usdhc1 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
+       assigned-clock-rates = <400000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc1>;
        pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
 };
 
 &usdhc2 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC2>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
        pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
index d7f03c6..3dc4411 100644 (file)
 };
 
 &usdhc1 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
+       assigned-clock-rates = <400000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc1>;
        pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
index 32ce149..6a55165 100644 (file)
        reg_3p3_main: regulator-3p3-main {
                compatible = "regulator-fixed";
                vin-supply = <&reg_12p0_main>;
-               regulator-name = "3V3V_MAIN";
+               regulator-name = "3V3_MAIN";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_gen_3p3: regulator-gen-3p3 {
+               compatible = "regulator-fixed";
+               vin-supply = <&reg_3p3_main>;
+               regulator-name = "GEN_3V3";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-always-on;
@@ -72,7 +81,7 @@
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_reg_usdhc2>;
                compatible = "regulator-fixed";
-               vin-supply = <&reg_3p3_main>;
+               vin-supply = <&reg_gen_3p3>;
                regulator-name = "3V3_SD";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
        pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
+       accelerometer@1c {
+               compatible = "fsl,mma8451";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_accel>;
+               reg = <0x1c>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-names = "INT2";
+               vdd-supply = <&reg_gen_3p3>;
+               vddio-supply = <&reg_gen_3p3>;
+       };
+
        ucs1002: charger@32 {
                compatible = "microchip,ucs1002";
                pinctrl-names = "default";
                reg = <0x2c>;
                reset-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
        };
+
+       watchdog@38 {
+               compatible = "zii,rave-wdt";
+               reg = <0x38>;
+       };
 };
 
 &i2c4 {
 };
 
 &usdhc1 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
+       assigned-clock-rates = <400000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc1>;
        pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
 };
 
 &usdhc2 {
+       assigned-clocks = <&clk IMX8MQ_CLK_USDHC2>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2>;
        pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
 };
 
 &iomuxc {
+       pinctrl_accel: accelgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20                0x41
+               >;
+       };
+
        pinctrl_fec1: fec1grp {
                fsl,pins = <
                        MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC                 0x3
index 55a3d1c..7f93194 100644 (file)
                        thermal-sensors = <&tmu 1>;
 
                        trips {
+                               gpu_alert: gpu-alert {
+                                       temperature = <80000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
                                gpu-crit {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "critical";
                                };
                        };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&gpu_alert>;
+                                       cooling-device =
+                                               <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
                };
 
                vpu-thermal {
                                         <&clk IMX8MQ_CLK_NAND_USDHC_BUS>,
                                         <&clk IMX8MQ_CLK_USDHC1_ROOT>;
                                clock-names = "ipg", "ahb", "per";
-                               assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>;
-                               assigned-clock-rates = <400000000>;
                                fsl,tuning-start-tap = <20>;
                                fsl,tuning-step = <2>;
                                bus-width = <4>;
                                 <&clk IMX8MQ_CLK_GPU_AXI>,
                                 <&clk IMX8MQ_CLK_GPU_AHB>;
                        clock-names = "core", "shader", "bus", "reg";
+                       #cooling-cells = <2>;
                        assigned-clocks = <&clk IMX8MQ_CLK_GPU_CORE_SRC>,
                                          <&clk IMX8MQ_CLK_GPU_SHADER_SRC>,
                                          <&clk IMX8MQ_CLK_GPU_AXI>,
index 91eef97..a3f8cf1 100644 (file)
 &usdhc1 {
        #address-cells = <1>;
        #size-cells = <0>;
+       assigned-clocks = <&clk IMX_CONN_SDHC0_CLK>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc1>;
        bus-width = <4>;
 
 /* SD */
 &usdhc2 {
+       assigned-clocks = <&clk IMX_CONN_SDHC1_CLK>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc2>;
        bus-width = <4>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dts b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dts
new file mode 100644 (file)
index 0000000..6b21a29
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2019 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-colibri.dtsi"
+#include "imx8qxp-colibri-eval-v3.dtsi"
+
+/ {
+       model = "Toradex Colibri iMX8QXP/DX on Colibri Evaluation Board V3";
+       compatible = "toradex,colibri-imx8x-eval-v3",
+                    "toradex,colibri-imx8x", "fsl,imx8qxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-colibri-eval-v3.dtsi
new file mode 100644 (file)
index 0000000..c7336f3
--- /dev/null
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2019 Toradex
+ */
+
+#include "dt-bindings/input/linux-event-codes.h"
+
+/ {
+       aliases {
+               rtc0 = &rtc_i2c;
+               rtc1 = &rtc;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpiokeys>;
+
+               wakeup {
+                       label = "Wake-Up";
+                       gpios = <&lsio_gpio3 10 GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_WAKEUP>;
+                       debounce-interval = <10>;
+                       wakeup-source;
+               };
+       };
+};
+
+&adma_i2c1 {
+       status = "okay";
+
+       /* M41T0M6 real time clock on carrier board */
+       rtc_i2c: rtc@68 {
+               compatible = "st,m41t0";
+               reg = <0x68>;
+       };
+};
+
+/* Colibri UART_B */
+&adma_lpuart0 {
+       status= "okay";
+};
+
+/* Colibri UART_C */
+&adma_lpuart2 {
+       status= "okay";
+};
+
+/* Colibri UART_A */
+&adma_lpuart3 {
+       status= "okay";
+};
+
+/* Colibri FastEthernet */
+&fec1 {
+       status = "okay";
+};
+
+/* Colibri SD/MMC Card */
+&usdhc2 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi
new file mode 100644 (file)
index 0000000..75f17a2
--- /dev/null
@@ -0,0 +1,598 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2019 Toradex
+ */
+
+#include "imx8qxp.dtsi"
+
+/ {
+       model = "Toradex Colibri iMX8QXP/DX Module";
+       compatible = "toradex,colibri-imx8x", "fsl,imx8qxp";
+
+       chosen {
+               stdout-path = &adma_lpuart3;
+       };
+
+       reg_module_3v3: regulator-module-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+/* On-module I2C */
+&adma_i2c0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c0>, <&pinctrl_sgtl5000_usb_clk>;
+       status = "okay";
+
+       /* Touch controller */
+       touchscreen@2c {
+               compatible = "adi,ad7879-1";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ad7879_int>;
+               reg = <0x2c>;
+               interrupt-parent = <&lsio_gpio3>;
+               interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+               touchscreen-max-pressure = <4096>;
+               adi,resistance-plate-x = <120>;
+               adi,first-conversion-delay = /bits/ 8 <3>;
+               adi,acquisition-time = /bits/ 8 <1>;
+               adi,median-filter-size = /bits/ 8 <2>;
+               adi,averaging = /bits/ 8 <1>;
+               adi,conversion-interval = /bits/ 8 <255>;
+       };
+};
+
+/* Colibri I2C */
+&adma_i2c1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+};
+
+/* Colibri UART_B */
+&adma_lpuart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart0>;
+};
+
+/* Colibri UART_C */
+&adma_lpuart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart2>;
+};
+
+/* Colibri UART_A */
+&adma_lpuart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart3>, <&pinctrl_lpuart3_ctrl>;
+};
+
+/* Colibri FastEthernet */
+&fec1 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&pinctrl_fec1>;
+       pinctrl-1 = <&pinctrl_fec1_sleep>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy0>;
+       fsl,magic-packet;
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@2 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       max-speed = <100>;
+                       reg = <2>;
+               };
+       };
+};
+
+/* On-module eMMC */
+&usdhc1 {
+       bus-width = <8>;
+       non-removable;
+       no-sd;
+       no-sdio;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+       status = "okay";
+};
+
+/* Colibri SD/MMC Card */
+&usdhc2 {
+       bus-width = <4>;
+       cd-gpios = <&lsio_gpio3 9 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_module_3v3>;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>;
+       disable-wp;
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ext_io0>, <&pinctrl_hog0>, <&pinctrl_hog1>;
+
+       /* On-module touch pen-down interrupt */
+       pinctrl_ad7879_int: ad7879intgrp {
+               fsl,pins = <
+                       IMX8QXP_MIPI_CSI0_I2C0_SCL_LSIO_GPIO3_IO05      0x21
+               >;
+       };
+
+       /* Colibri Analogue Inputs */
+       pinctrl_adc0: adc0grp {
+               fsl,pins = <
+                       IMX8QXP_ADC_IN0_ADMA_ADC_IN0                    0x60            /* SODIMM   8 */
+                       IMX8QXP_ADC_IN1_ADMA_ADC_IN1                    0x60            /* SODIMM   6 */
+                       IMX8QXP_ADC_IN4_ADMA_ADC_IN4                    0x60            /* SODIMM   4 */
+                       IMX8QXP_ADC_IN5_ADMA_ADC_IN5                    0x60            /* SODIMM   2 */
+               >;
+       };
+
+       pinctrl_can_int: canintgrp {
+               fsl,pins = <
+                       IMX8QXP_QSPI0A_DQS_LSIO_GPIO3_IO13              0x40            /* SODIMM  73 */
+               >;
+       };
+
+       pinctrl_csi_ctl: csictlgrp {
+               fsl,pins = <
+                       IMX8QXP_QSPI0A_SS0_B_LSIO_GPIO3_IO14            0x20            /* SODIMM  77 */
+                       IMX8QXP_QSPI0A_SS1_B_LSIO_GPIO3_IO15            0x20            /* SODIMM  89 */
+               >;
+       };
+
+       pinctrl_ext_io0: extio0grp {
+               fsl,pins = <
+                       IMX8QXP_ENET0_RGMII_RXD3_LSIO_GPIO5_IO08        0x06000040      /* SODIMM 135 */
+               >;
+       };
+
+       /* Colibri Ethernet: On-module 100Mbps PHY Micrel KSZ8041 */
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       IMX8QXP_ENET0_MDC_CONN_ENET0_MDC                        0x06000020
+                       IMX8QXP_ENET0_MDIO_CONN_ENET0_MDIO                      0x06000020
+                       IMX8QXP_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL      0x61
+                       IMX8QXP_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_OUT          0x06000061
+                       IMX8QXP_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0          0x61
+                       IMX8QXP_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1          0x61
+                       IMX8QXP_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL      0x61
+                       IMX8QXP_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0          0x61
+                       IMX8QXP_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1          0x61
+                       IMX8QXP_ENET0_RGMII_RXD2_CONN_ENET0_RMII_RX_ER          0x61
+               >;
+       };
+
+       pinctrl_fec1_sleep: fec1slpgrp {
+               fsl,pins = <
+                       IMX8QXP_ENET0_MDC_LSIO_GPIO5_IO11               0x06000041
+                       IMX8QXP_ENET0_MDIO_LSIO_GPIO5_IO10              0x06000041
+                       IMX8QXP_ENET0_RGMII_TX_CTL_LSIO_GPIO4_IO30      0x41
+                       IMX8QXP_ENET0_RGMII_TXC_LSIO_GPIO4_IO29         0x41
+                       IMX8QXP_ENET0_RGMII_TXD0_LSIO_GPIO4_IO31        0x41
+                       IMX8QXP_ENET0_RGMII_TXD1_LSIO_GPIO5_IO00        0x41
+                       IMX8QXP_ENET0_RGMII_RX_CTL_LSIO_GPIO5_IO04      0x41
+                       IMX8QXP_ENET0_RGMII_RXD0_LSIO_GPIO5_IO05        0x41
+                       IMX8QXP_ENET0_RGMII_RXD1_LSIO_GPIO5_IO06        0x41
+                       IMX8QXP_ENET0_RGMII_RXD2_LSIO_GPIO5_IO07        0x41
+               >;
+       };
+
+       /* Colibri optional CAN on UART_B RTS/CTS */
+       pinctrl_flexcan1: flexcan0grp {
+               fsl,pins = <
+                       IMX8QXP_FLEXCAN0_TX_ADMA_FLEXCAN0_TX            0x21            /* SODIMM  32 */
+                       IMX8QXP_FLEXCAN0_RX_ADMA_FLEXCAN0_RX            0x21            /* SODIMM  34 */
+               >;
+       };
+
+       /* Colibri optional CAN on PS2 */
+       pinctrl_flexcan2: flexcan1grp {
+               fsl,pins = <
+                       IMX8QXP_FLEXCAN1_TX_ADMA_FLEXCAN1_TX            0x21            /* SODIMM  55 */
+                       IMX8QXP_FLEXCAN1_RX_ADMA_FLEXCAN1_RX            0x21            /* SODIMM  63 */
+               >;
+       };
+
+       /* Colibri optional CAN on UART_A TXD/RXD */
+       pinctrl_flexcan3: flexcan2grp {
+               fsl,pins = <
+                       IMX8QXP_FLEXCAN2_TX_ADMA_FLEXCAN2_TX            0x21            /* SODIMM  35 */
+                       IMX8QXP_FLEXCAN2_RX_ADMA_FLEXCAN2_RX            0x21            /* SODIMM  33 */
+               >;
+       };
+
+       /* Colibri LCD Back-Light GPIO */
+       pinctrl_gpio_bl_on: gpioblongrp {
+               fsl,pins = <
+                       IMX8QXP_QSPI0A_DATA3_LSIO_GPIO3_IO12            0x60            /* SODIMM  71 */
+               >;
+       };
+
+       pinctrl_gpiokeys: gpiokeysgrp {
+               fsl,pins = <
+                       IMX8QXP_QSPI0A_DATA1_LSIO_GPIO3_IO10            0x06700041      /* SODIMM  45 */
+               >;
+       };
+
+       pinctrl_hog0: hog0grp {
+               fsl,pins = <
+                       IMX8QXP_ENET0_RGMII_TXD3_LSIO_GPIO5_IO02        0x06000020      /* SODIMM  65 */
+                       IMX8QXP_CSI_D07_CI_PI_D09                       0x61            /* SODIMM  65 */
+                       IMX8QXP_QSPI0A_DATA2_LSIO_GPIO3_IO11            0x20            /* SODIMM  69 */
+                       IMX8QXP_SAI0_TXC_LSIO_GPIO0_IO26                0x20            /* SODIMM  79 */
+                       IMX8QXP_CSI_D02_CI_PI_D04                       0x61            /* SODIMM  79 */
+                       IMX8QXP_ENET0_RGMII_RXC_LSIO_GPIO5_IO03         0x06000020      /* SODIMM  85 */
+                       IMX8QXP_CSI_D06_CI_PI_D08                       0x61            /* SODIMM  85 */
+                       IMX8QXP_QSPI0B_SCLK_LSIO_GPIO3_IO17             0x20            /* SODIMM  95 */
+                       IMX8QXP_SAI0_RXD_LSIO_GPIO0_IO27                0x20            /* SODIMM  97 */
+                       IMX8QXP_CSI_D03_CI_PI_D05                       0x61            /* SODIMM  97 */
+                       IMX8QXP_QSPI0B_DATA0_LSIO_GPIO3_IO18            0x20            /* SODIMM  99 */
+                       IMX8QXP_SAI0_TXFS_LSIO_GPIO0_IO28               0x20            /* SODIMM 101 */
+                       IMX8QXP_CSI_D00_CI_PI_D02                       0x61            /* SODIMM 101 */
+                       IMX8QXP_SAI0_TXD_LSIO_GPIO0_IO25                0x20            /* SODIMM 103 */
+                       IMX8QXP_CSI_D01_CI_PI_D03                       0x61            /* SODIMM 103 */
+                       IMX8QXP_QSPI0B_DATA1_LSIO_GPIO3_IO19            0x20            /* SODIMM 105 */
+                       IMX8QXP_QSPI0B_DATA2_LSIO_GPIO3_IO20            0x20            /* SODIMM 107 */
+                       IMX8QXP_USB_SS3_TC2_LSIO_GPIO4_IO05             0x20            /* SODIMM 127 */
+                       IMX8QXP_USB_SS3_TC3_LSIO_GPIO4_IO06             0x20            /* SODIMM 131 */
+                       IMX8QXP_USB_SS3_TC1_LSIO_GPIO4_IO04             0x20            /* SODIMM 133 */
+                       IMX8QXP_CSI_PCLK_LSIO_GPIO3_IO00                0x20            /* SODIMM  96 */
+                       IMX8QXP_QSPI0B_DATA3_LSIO_GPIO3_IO21            0x20            /* SODIMM  98 */
+                       IMX8QXP_SAI1_RXFS_LSIO_GPIO0_IO31               0x20            /* SODIMM 100 */
+                       IMX8QXP_QSPI0B_DQS_LSIO_GPIO3_IO22              0x20            /* SODIMM 102 */
+                       IMX8QXP_QSPI0B_SS0_B_LSIO_GPIO3_IO23            0x20            /* SODIMM 104 */
+                       IMX8QXP_QSPI0B_SS1_B_LSIO_GPIO3_IO24            0x20            /* SODIMM 106 */
+               >;
+       };
+
+       pinctrl_hog1: hog1grp {
+               fsl,pins = <
+                       IMX8QXP_CSI_MCLK_LSIO_GPIO3_IO01                0x20            /* SODIMM  75 */
+                       IMX8QXP_QSPI0A_SCLK_LSIO_GPIO3_IO16             0x20            /* SODIMM  93 */
+               >;
+       };
+
+       /*
+        * This pin is used in the SCFW as a UART. Using it from
+        * Linux would require rewritting the SCFW board file.
+        */
+       pinctrl_hog_scfw: hogscfwgrp {
+               fsl,pins = <
+                       IMX8QXP_SCU_GPIO0_00_LSIO_GPIO2_IO03            0x20            /* SODIMM 144 */
+               >;
+       };
+
+       /* On Module I2C */
+       pinctrl_i2c0: i2c0grp {
+               fsl,pins = <
+                       IMX8QXP_MIPI_CSI0_GPIO0_00_ADMA_I2C0_SCL        0x06000021
+                       IMX8QXP_MIPI_CSI0_GPIO0_01_ADMA_I2C0_SDA        0x06000021
+               >;
+       };
+
+       /* MIPI DSI I2C accessible on SODIMM (X1) and FFC (X2) */
+       pinctrl_i2c0_mipi_lvds0: i2c0mipilvds0grp {
+               fsl,pins = <
+                       IMX8QXP_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL   0xc6000020      /* SODIMM 140 */
+                       IMX8QXP_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA   0xc6000020      /* SODIMM 142 */
+               >;
+       };
+
+       /* MIPI CSI I2C accessible on SODIMM (X1) and FFC (X3) */
+       pinctrl_i2c0_mipi_lvds1: i2c0mipilvds1grp {
+               fsl,pins = <
+                       IMX8QXP_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL   0xc6000020      /* SODIMM 186 */
+                       IMX8QXP_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA   0xc6000020      /* SODIMM 188 */
+               >;
+       };
+
+       /* Colibri I2C */
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       IMX8QXP_MIPI_DSI0_GPIO0_00_ADMA_I2C1_SCL        0x06000021      /* SODIMM 196 */
+                       IMX8QXP_MIPI_DSI0_GPIO0_01_ADMA_I2C1_SDA        0x06000021      /* SODIMM 194 */
+               >;
+       };
+
+       /* Colibri Parallel RGB LCD Interface */
+       pinctrl_lcdif: lcdifgrp {
+               fsl,pins = <
+                       IMX8QXP_MCLK_OUT0_ADMA_LCDIF_CLK                0x60            /* SODIMM  56 */
+                       IMX8QXP_SPI3_CS0_ADMA_LCDIF_HSYNC               0x60            /* SODIMM  68 */
+                       IMX8QXP_MCLK_IN0_ADMA_LCDIF_VSYNC               0x60            /* SODIMM  82 */
+                       IMX8QXP_MCLK_IN1_ADMA_LCDIF_EN                  0x60            /* SODIMM  44 */
+                       IMX8QXP_USDHC1_RESET_B_LSIO_GPIO4_IO19          0x60            /* SODIMM  44 */
+                       IMX8QXP_ESAI0_FSR_ADMA_LCDIF_D00                0x60            /* SODIMM  76 */
+                       IMX8QXP_USDHC1_WP_LSIO_GPIO4_IO21               0x60            /* SODIMM  76 */
+                       IMX8QXP_ESAI0_FST_ADMA_LCDIF_D01                0x60            /* SODIMM  70 */
+                       IMX8QXP_ESAI0_SCKR_ADMA_LCDIF_D02               0x60            /* SODIMM  60 */
+                       IMX8QXP_ESAI0_SCKT_ADMA_LCDIF_D03               0x60            /* SODIMM  58 */
+                       IMX8QXP_ESAI0_TX0_ADMA_LCDIF_D04                0x60            /* SODIMM  78 */
+                       IMX8QXP_ESAI0_TX1_ADMA_LCDIF_D05                0x60            /* SODIMM  72 */
+                       IMX8QXP_ESAI0_TX2_RX3_ADMA_LCDIF_D06            0x60            /* SODIMM  80 */
+                       IMX8QXP_ESAI0_TX3_RX2_ADMA_LCDIF_D07            0x60            /* SODIMM  46 */
+                       IMX8QXP_ESAI0_TX4_RX1_ADMA_LCDIF_D08            0x60            /* SODIMM  62 */
+                       IMX8QXP_ESAI0_TX5_RX0_ADMA_LCDIF_D09            0x60            /* SODIMM  48 */
+                       IMX8QXP_SPDIF0_RX_ADMA_LCDIF_D10                0x60            /* SODIMM  74 */
+                       IMX8QXP_SPDIF0_TX_ADMA_LCDIF_D11                0x60            /* SODIMM  50 */
+                       IMX8QXP_SPDIF0_EXT_CLK_ADMA_LCDIF_D12           0x60            /* SODIMM  52 */
+                       IMX8QXP_SPI3_SCK_ADMA_LCDIF_D13                 0x60            /* SODIMM  54 */
+                       IMX8QXP_SPI3_SDO_ADMA_LCDIF_D14                 0x60            /* SODIMM  66 */
+                       IMX8QXP_SPI3_SDI_ADMA_LCDIF_D15                 0x60            /* SODIMM  64 */
+                       IMX8QXP_SPI3_CS1_ADMA_LCDIF_D16                 0x60            /* SODIMM  57 */
+                       IMX8QXP_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01        0x60            /* SODIMM  57 */
+                       IMX8QXP_UART1_CTS_B_ADMA_LCDIF_D17              0x60            /* SODIMM  61 */
+               >;
+       };
+
+       /* Colibri SPI */
+       pinctrl_lpspi2: lpspi2grp {
+               fsl,pins = <
+                       IMX8QXP_SPI2_CS0_LSIO_GPIO1_IO00                0x21            /* SODIMM  86 */
+                       IMX8QXP_SPI2_SDO_ADMA_SPI2_SDO                  0x06000040      /* SODIMM  92 */
+                       IMX8QXP_SPI2_SDI_ADMA_SPI2_SDI                  0x06000040      /* SODIMM  90 */
+                       IMX8QXP_SPI2_SCK_ADMA_SPI2_SCK                  0x06000040      /* SODIMM  88 */
+               >;
+       };
+
+       /* Colibri UART_B */
+       pinctrl_lpuart0: lpuart0grp {
+               fsl,pins = <
+                       IMX8QXP_UART0_RX_ADMA_UART0_RX                  0x06000020      /* SODIMM  36 */
+                       IMX8QXP_UART0_TX_ADMA_UART0_TX                  0x06000020      /* SODIMM  38 */
+                       IMX8QXP_FLEXCAN0_RX_ADMA_UART0_RTS_B            0x06000020      /* SODIMM  34 */
+                       IMX8QXP_FLEXCAN0_TX_ADMA_UART0_CTS_B            0x06000020      /* SODIMM  32 */
+               >;
+       };
+
+       /* Colibri UART_C */
+       pinctrl_lpuart2: lpuart2grp {
+               fsl,pins = <
+                       IMX8QXP_UART2_RX_ADMA_UART2_RX                  0x06000020      /* SODIMM  19 */
+                       IMX8QXP_UART2_TX_ADMA_UART2_TX                  0x06000020      /* SODIMM  21 */
+               >;
+       };
+
+       /* Colibri UART_A */
+       pinctrl_lpuart3: lpuart3grp {
+               fsl,pins = <
+                       IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX               0x06000020      /* SODIMM  33 */
+                       IMX8QXP_FLEXCAN2_TX_ADMA_UART3_TX               0x06000020      /* SODIMM  35 */
+               >;
+       };
+
+       /* Colibri UART_A Control */
+       pinctrl_lpuart3_ctrl: lpuart3ctrlgrp {
+               fsl,pins = <
+                       IMX8QXP_MIPI_DSI1_GPIO0_01_LSIO_GPIO2_IO00      0x20            /* SODIMM  23 */
+                       IMX8QXP_SAI1_RXD_LSIO_GPIO0_IO29                0x20            /* SODIMM  25 */
+                       IMX8QXP_SAI1_RXC_LSIO_GPIO0_IO30                0x20            /* SODIMM  27 */
+                       IMX8QXP_CSI_RESET_LSIO_GPIO3_IO03               0x20            /* SODIMM  29 */
+                       IMX8QXP_USDHC1_CD_B_LSIO_GPIO4_IO22             0x20            /* SODIMM  31 */
+                       IMX8QXP_CSI_EN_LSIO_GPIO3_IO02                  0x20            /* SODIMM  37 */
+               >;
+       };
+
+       /* On module wifi module */
+       pinctrl_pcieb: pciebgrp {
+               fsl,pins = <
+                       IMX8QXP_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01     0x04000061      /* SODIMM 178 */
+                       IMX8QXP_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02       0x04000061      /* SODIMM  94 */
+                       IMX8QXP_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00      0x60            /* SODIMM  81 */
+               >;
+       };
+
+       /* Colibri PWM_A */
+       pinctrl_pwm_a: pwmagrp {
+       /* both pins are connected together, reserve the unused CSI_D05 */
+               fsl,pins = <
+                       IMX8QXP_CSI_D05_CI_PI_D07                       0x61            /* SODIMM  59 */
+                       IMX8QXP_SPI0_CS1_ADMA_LCD_PWM0_OUT              0x60            /* SODIMM  59 */
+               >;
+       };
+
+       /* Colibri PWM_B */
+       pinctrl_pwm_b: pwmbgrp {
+               fsl,pins = <
+                       IMX8QXP_UART1_TX_LSIO_PWM0_OUT                  0x60            /* SODIMM  28 */
+               >;
+       };
+
+       /* Colibri PWM_C */
+       pinctrl_pwm_c: pwmcgrp {
+               fsl,pins = <
+                       IMX8QXP_UART1_RX_LSIO_PWM1_OUT                  0x60            /* SODIMM  30 */
+               >;
+       };
+
+       /* Colibri PWM_D */
+       pinctrl_pwm_d: pwmdgrp {
+       /* both pins are connected together, reserve the unused CSI_D04 */
+               fsl,pins = <
+                       IMX8QXP_CSI_D04_CI_PI_D06                       0x61            /* SODIMM  67 */
+                       IMX8QXP_UART1_RTS_B_LSIO_PWM2_OUT               0x60            /* SODIMM  67 */
+               >;
+       };
+
+       /* On-module I2S */
+       pinctrl_sai0: sai0grp {
+               fsl,pins = <
+                       IMX8QXP_SPI0_SDI_ADMA_SAI0_TXD                  0x06000040
+                       IMX8QXP_SPI0_CS0_ADMA_SAI0_RXD                  0x06000040
+                       IMX8QXP_SPI0_SCK_ADMA_SAI0_TXC                  0x06000040
+                       IMX8QXP_SPI0_SDO_ADMA_SAI0_TXFS                 0x06000040
+               >;
+       };
+
+       /* Colibri Audio Analogue Microphone GND */
+       pinctrl_sgtl5000: sgtl5000grp {
+               fsl,pins = <
+                       /* MIC GND EN */
+                       IMX8QXP_MIPI_CSI0_I2C0_SDA_LSIO_GPIO3_IO06      0x41
+               >;
+       };
+
+       /* On-module SGTL5000 clock */
+       pinctrl_sgtl5000_usb_clk: sgtl5000usbclkgrp {
+               fsl,pins = <
+                       IMX8QXP_ADC_IN3_ADMA_ACM_MCLK_OUT0              0x21
+               >;
+       };
+
+       /* On-module USB interrupt */
+       pinctrl_usb3503a: usb3503agrp {
+               fsl,pins = <
+                       IMX8QXP_MIPI_CSI0_MCLK_OUT_LSIO_GPIO3_IO04      0x61
+               >;
+       };
+
+       /* Colibri USB Client Cable Detect */
+       pinctrl_usbc_det: usbcdetgrp {
+               fsl,pins = <
+                       IMX8QXP_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09   0x06000040      /* SODIMM 137 */
+               >;
+       };
+
+       /* USB Host Power Enable */
+       pinctrl_usbh1_reg: usbh1reggrp {
+               fsl,pins = <
+                       IMX8QXP_USB_SS3_TC0_LSIO_GPIO4_IO03             0x06000040      /* SODIMM 129 */
+               >;
+       };
+
+       /* On-module eMMC */
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK                0x06000041
+                       IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD                0x21
+                       IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0            0x21
+                       IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1            0x21
+                       IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2            0x21
+                       IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3            0x21
+                       IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4            0x21
+                       IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5            0x21
+                       IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6            0x21
+                       IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7            0x21
+                       IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE          0x41
+                       IMX8QXP_EMMC0_RESET_B_CONN_EMMC0_RESET_B        0x21
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+               fsl,pins = <
+                       IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK                0x06000041
+                       IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD                0x21
+                       IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0            0x21
+                       IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1            0x21
+                       IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2            0x21
+                       IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3            0x21
+                       IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4            0x21
+                       IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5            0x21
+                       IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6            0x21
+                       IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7            0x21
+                       IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE          0x41
+                       IMX8QXP_EMMC0_RESET_B_CONN_EMMC0_RESET_B        0x21
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+               fsl,pins = <
+                       IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK                0x06000041
+                       IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD                0x21
+                       IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0            0x21
+                       IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1            0x21
+                       IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2            0x21
+                       IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3            0x21
+                       IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4            0x21
+                       IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5            0x21
+                       IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6            0x21
+                       IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7            0x21
+                       IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE          0x41
+                       IMX8QXP_EMMC0_RESET_B_CONN_EMMC0_RESET_B        0x21
+               >;
+       };
+
+       /* Colibri SD/MMC Card Detect */
+       pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+               fsl,pins = <
+                       IMX8QXP_QSPI0A_DATA0_LSIO_GPIO3_IO09            0x06000021      /* SODIMM  43 */
+               >;
+       };
+
+       pinctrl_usdhc2_gpio_sleep: usdhc2gpioslpgrp {
+               fsl,pins = <
+                       IMX8QXP_QSPI0A_DATA0_LSIO_GPIO3_IO09            0x60            /* SODIMM  43 */
+               >;
+       };
+
+       /* Colibri SD/MMC Card */
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK              0x06000041      /* SODIMM  47 */
+                       IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD              0x21            /* SODIMM 190 */
+                       IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0          0x21            /* SODIMM 192 */
+                       IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1          0x21            /* SODIMM  49 */
+                       IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2          0x21            /* SODIMM  51 */
+                       IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3          0x21            /* SODIMM  53 */
+                       IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT      0x21
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+               fsl,pins = <
+                       IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK              0x06000041      /* SODIMM  47 */
+                       IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD              0x21            /* SODIMM 190 */
+                       IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0          0x21            /* SODIMM 192 */
+                       IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1          0x21            /* SODIMM  49 */
+                       IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2          0x21            /* SODIMM  51 */
+                       IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3          0x21            /* SODIMM  53 */
+                       IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT      0x21
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+               fsl,pins = <
+                       IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK              0x06000041      /* SODIMM  47 */
+                       IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD              0x21            /* SODIMM 190 */
+                       IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0          0x21            /* SODIMM 192 */
+                       IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1          0x21            /* SODIMM  49 */
+                       IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2          0x21            /* SODIMM  51 */
+                       IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3          0x21            /* SODIMM  53 */
+                       IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT      0x21
+               >;
+       };
+
+       pinctrl_usdhc2_sleep: usdhc2slpgrp {
+               fsl,pins = <
+                       IMX8QXP_USDHC1_CLK_LSIO_GPIO4_IO23              0x60            /* SODIMM  47 */
+                       IMX8QXP_USDHC1_CMD_LSIO_GPIO4_IO24              0x60            /* SODIMM 190 */
+                       IMX8QXP_USDHC1_DATA0_LSIO_GPIO4_IO25            0x60            /* SODIMM 192 */
+                       IMX8QXP_USDHC1_DATA1_LSIO_GPIO4_IO26            0x60            /* SODIMM  49 */
+                       IMX8QXP_USDHC1_DATA2_LSIO_GPIO4_IO27            0x60            /* SODIMM  51 */
+                       IMX8QXP_USDHC1_DATA3_LSIO_GPIO4_IO28            0x60            /* SODIMM  53 */
+                       IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT      0x21
+               >;
+       };
+
+       pinctrl_wifi: wifigrp {
+               fsl,pins = <
+                       IMX8QXP_SCU_BOOT_MODE3_SCU_DSC_RTC_CLOCK_OUTPUT_32K     0x20
+               >;
+       };
+};
index 1946805..d3d26cc 100644 (file)
 };
 
 &usdhc1 {
+       assigned-clocks = <&clk IMX_CONN_SDHC0_CLK>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc1>;
        bus-width = <8>;
 };
 
 &usdhc2 {
+       assigned-clocks = <&clk IMX_CONN_SDHC1_CLK>;
+       assigned-clock-rates = <200000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc2>;
        bus-width = <4>;
 &adma_dsp {
        status = "okay";
 };
+
+&scu_key {
+       status = "okay";
+};
index 1133b41..9646a41 100644 (file)
@@ -8,6 +8,7 @@
 #include <dt-bindings/clock/imx8-clock.h>
 #include <dt-bindings/firmware/imx/rsrc.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/pinctrl/pads-imx8qxp.h>
 
                        #power-domain-cells = <1>;
                };
 
+               scu_key: scu-key {
+                       compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
+                       linux,keycodes = <KEY_POWER>;
+                       status = "disabled";
+               };
+
                rtc: rtc {
                        compatible = "fsl,imx8qxp-sc-rtc";
                };
                                 <&conn_lpcg IMX_CONN_LPCG_SDHC0_PER_CLK>,
                                 <&conn_lpcg IMX_CONN_LPCG_SDHC0_HCLK>;
                        clock-names = "ipg", "per", "ahb";
-                       assigned-clocks = <&clk IMX_CONN_SDHC0_CLK>;
-                       assigned-clock-rates = <200000000>;
                        power-domains = <&pd IMX_SC_R_SDHC_0>;
                        status = "disabled";
                };
                                 <&conn_lpcg IMX_CONN_LPCG_SDHC1_PER_CLK>,
                                 <&conn_lpcg IMX_CONN_LPCG_SDHC1_HCLK>;
                        clock-names = "ipg", "per", "ahb";
-                       assigned-clocks = <&clk IMX_CONN_SDHC1_CLK>;
-                       assigned-clock-rates = <200000000>;
                        power-domains = <&pd IMX_SC_R_SDHC_1>;
                        fsl,tuning-start-tap = <20>;
                        fsl,tuning-step= <2>;
                                 <&conn_lpcg IMX_CONN_LPCG_SDHC2_PER_CLK>,
                                 <&conn_lpcg IMX_CONN_LPCG_SDHC2_HCLK>;
                        clock-names = "ipg", "per", "ahb";
-                       assigned-clocks = <&clk IMX_CONN_SDHC2_CLK>;
-                       assigned-clock-rates = <200000000>;
                        power-domains = <&pd IMX_SC_R_SDHC_2>;
                        status = "disabled";
                };
diff --git a/arch/arm64/boot/dts/freescale/s32v234-evb.dts b/arch/arm64/boot/dts/freescale/s32v234-evb.dts
new file mode 100644 (file)
index 0000000..4b80251
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ */
+
+/dts-v1/;
+#include "s32v234.dtsi"
+
+/ {
+       model = "NXP S32V234-EVB2 Board";
+       compatible = "fsl,s32v234-evb", "fsl,s32v234";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32v234.dtsi b/arch/arm64/boot/dts/freescale/s32v234.dtsi
new file mode 100644 (file)
index 0000000..e746b9c
--- /dev/null
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2016-2018 NXP
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+       compatible = "fsl,s32v234";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x0>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x80000000>;
+                       next-level-cache = <&cluster0_l2_cache>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x1>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x80000000>;
+                       next-level-cache = <&cluster0_l2_cache>;
+               };
+
+               cpu2: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x100>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x80000000>;
+                       next-level-cache = <&cluster1_l2_cache>;
+               };
+
+               cpu3: cpu@101 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x101>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x0 0x80000000>;
+                       next-level-cache = <&cluster1_l2_cache>;
+               };
+
+               cluster0_l2_cache: l2-cache0 {
+                       compatible = "cache";
+               };
+
+               cluster1_l2_cache: l2-cache1 {
+                       compatible = "cache";
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+                                         IRQ_TYPE_LEVEL_LOW)>;
+               /* clock-frequency might be modified by u-boot, depending on the
+                * chip version.
+                */
+               clock-frequency = <10000000>;
+       };
+
+       gic: interrupt-controller@7d001000 {
+               compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0 0x7d001000 0 0x1000>,
+                     <0 0x7d002000 0 0x2000>,
+                     <0 0x7d004000 0 0x2000>,
+                     <0 0x7d006000 0 0x2000>;
+               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+                                        IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       soc {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "simple-bus";
+               interrupt-parent = <&gic>;
+               ranges;
+
+               aips0: aips-bus@40000000 {
+                       compatible = "simple-bus";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       interrupt-parent = <&gic>;
+                       reg = <0x0 0x40000000 0x0 0x7d000>;
+                       ranges;
+
+                       uart0: serial@40053000 {
+                               compatible = "fsl,s32v234-linflexuart";
+                               reg = <0x0 0x40053000 0x0 0x1000>;
+                               interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
+                               status = "disabled";
+                       };
+               };
+
+               aips1: aips-bus@40080000 {
+                       compatible = "simple-bus";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       interrupt-parent = <&gic>;
+                       reg = <0x0 0x40080000 0x0 0x70000>;
+                       ranges;
+
+                       uart1: serial@400bc000 {
+                               compatible = "fsl,s32v234-linflexuart";
+                               reg = <0x0 0x400bc000 0x0 0x1000>;
+                               interrupts = <GIC_SPI 60 IRQ_TYPE_EDGE_RISING>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
index 108e2a4..2072b63 100644 (file)
                        compatible = "hisilicon,hi6220-aoctrl", "syscon";
                        reg = <0x0 0xf7800000 0x0 0x2000>;
                        #clock-cells = <1>;
+                       #reset-cells = <1>;
                };
 
                sys_ctrl: sys_ctrl@f7030000 {
                        clock-names = "apb_pclk";
                        cpu = <&cpu7>;
                };
+
+               mali: gpu@f4080000 {
+                       compatible = "hisilicon,hi6220-mali", "arm,mali-450";
+                       reg = <0x0 0xf4080000 0x0 0x00040000>;
+                       interrupt-parent = <&gic>;
+                       interrupts =    <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_PPI 126 IRQ_TYPE_LEVEL_HIGH>;
+
+                       interrupt-names = "gp",
+                                         "gpmmu",
+                                         "pp",
+                                         "pp0",
+                                         "ppmmu0",
+                                         "pp1",
+                                         "ppmmu1",
+                                         "pp2",
+                                         "ppmmu2",
+                                         "pp3",
+                                         "ppmmu3";
+                       clocks = <&media_ctrl HI6220_G3D_CLK>,
+                                <&media_ctrl HI6220_G3D_PCLK>;
+                       clock-names = "core", "bus";
+                       assigned-clocks = <&media_ctrl HI6220_G3D_CLK>,
+                                         <&media_ctrl HI6220_G3D_PCLK>;
+                       assigned-clock-rates = <500000000>, <144000000>;
+                       reset-names = "ao_g3d", "media_g3d";
+                       resets = <&ao_ctrl AO_G3D>, <&media_ctrl MEDIA_G3D>;
+               };
        };
 };
 
index 36abc25..94090c6 100644 (file)
        #address-cells = <2>;
        #size-cells = <2>;
 
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               service_reserved: svcbuffer@0 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x0 0x0 0x0 0x1000000>;
+                       alignment = <0x1000>;
+                       no-map;
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                interrupt-parent = <&intc>;
                ranges = <0 0 0 0xffffffff>;
 
+               base_fpga_region {
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       compatible = "fpga-region";
+                       fpga-mgr = <&fpga_mgr>;
+               };
+
                gmac0: ethernet@ff800000 {
                        compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
                        reg = <0xff800000 0x2000>;
 
                        status = "disabled";
                };
+
+               firmware {
+                       svc {
+                               compatible = "intel,stratix10-svc";
+                               method = "smc";
+                               memory-region = <&service_reserved>;
+
+                               fpga_mgr: fpga-mgr {
+                                       compatible = "intel,stratix10-soc-fpga-mgr";
+                               };
+                       };
+               };
        };
 };
index 7814a9e..e794a12 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       leds {
+               compatible = "gpio-leds";
+               hps0 {
+                       label = "hps_led0";
+                       gpios = <&portb 20 GPIO_ACTIVE_HIGH>;
+               };
+
+               hps1 {
+                       label = "hps_led1";
+                       gpios = <&portb 19 GPIO_ACTIVE_HIGH>;
+               };
+
+               hps2 {
+                       label = "hps_led2";
+                       gpios = <&portb 21 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
        memory {
                device_type = "memory";
                /* We expect the bootloader to fill in the reg */
        status = "okay";
 };
 
+&usb0 {
+       status = "okay";
+       disable-over-current;
+};
+
 &watchdog0 {
        status = "okay";
 };
+
+&qspi {
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "mt25qu02g";
+               reg = <0>;
+               spi-max-frequency = <100000000>;
+
+               m25p,fast-read;
+               cdns,page-size = <256>;
+               cdns,block-size = <16>;
+               cdns,read-delay = <1>;
+               cdns,tshsl-ns = <50>;
+               cdns,tsd2d-ns = <50>;
+               cdns,tchsh-ns = <4>;
+               cdns,tslch-ns = <4>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       qspi_boot: partition@0 {
+                               label = "Boot and fpga data";
+                               reg = <0x0 0x034B0000>;
+                       };
+
+                       qspi_rootfs: partition@34B0000 {
+                               label = "Root Filesystem - JFFS2";
+                               reg = <0x034B0000 0x0EB50000>;
+                       };
+               };
+       };
+};
index c8dc9c2..64f3b13 100644 (file)
        amba {
                #address-cells = <2>;
                #size-cells = <1>;
-               #interrupts-cells = <3>;
+               #interrupt-cells = <3>;
 
                compatible = "simple-bus";
                interrupt-parent = <&gic>;
index 82c6645..ac23592 100644 (file)
        amba {
                #address-cells = <2>;
                #size-cells = <1>;
-               #interrupts-cells = <3>;
+               #interrupt-cells = <3>;
 
                compatible = "simple-bus";
                interrupt-parent = <&gic>;
index 243338c..f1b5127 100644 (file)
@@ -10,3 +10,6 @@ dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin-singleshot.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-8080-db.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += cn9130-db.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += cn9131-db.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += cn9132-db.dtb
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts
new file mode 100644 (file)
index 0000000..bd9ed9d
--- /dev/null
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board with eMMC
+ * Copyright (C) 2018 Marvell
+ *
+ * Romain Perier <romain.perier@free-electrons.com>
+ * Konstantin Porotchkin <kostap@marvell.com>
+ *
+ */
+/*
+ * Schematic available at http://espressobin.net/wp-content/uploads/2017/08/ESPRESSObin_V5_Schematics.pdf
+ */
+
+#include "armada-3720-espressobin.dtsi"
+
+/ {
+       model = "Globalscale Marvell ESPRESSOBin Board (eMMC)";
+       compatible = "globalscale,espressobin-emmc", "globalscale,espressobin",
+                    "marvell,armada3720", "marvell,armada3710";
+};
+
+/* U11 */
+&sdhci0 {
+       non-removable;
+       bus-width = <8>;
+       mmc-ddr-1_8v;
+       mmc-hs400-1_8v;
+       marvell,xenon-emmc;
+       marvell,xenon-tun-count = <9>;
+       marvell,pad-type = "fixed-1-8v";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc_pins>;
+       status = "okay";
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+       mmccard: mmccard@0 {
+               compatible = "mmc-card";
+               reg = <0>;
+       };
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts
new file mode 100644 (file)
index 0000000..6e876a6
--- /dev/null
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7 with eMMC
+ * Copyright (C) 2018 Marvell
+ *
+ * Romain Perier <romain.perier@free-electrons.com>
+ * Konstantin Porotchkin <kostap@marvell.com>
+ *
+ */
+/*
+ * Schematic available at http://wiki.espressobin.net/tiki-download_file.php?fileId=200
+ */
+
+#include "armada-3720-espressobin.dtsi"
+
+/ {
+       model = "Globalscale Marvell ESPRESSOBin Board V7 (eMMC)";
+       compatible = "globalscale,espressobin-v7-emmc", "globalscale,espressobin-v7",
+                    "globalscale,espressobin", "marvell,armada3720",
+                    "marvell,armada3710";
+};
+
+&switch0 {
+       ports {
+               port@1 {
+                       reg = <1>;
+                       label = "lan1";
+                       phy-handle = <&switch0phy0>;
+               };
+
+               port@3 {
+                       reg = <3>;
+                       label = "wan";
+                       phy-handle = <&switch0phy2>;
+               };
+       };
+};
+
+/* U11 */
+&sdhci0 {
+       non-removable;
+       bus-width = <8>;
+       mmc-ddr-1_8v;
+       mmc-hs400-1_8v;
+       marvell,xenon-emmc;
+       marvell,xenon-tun-count = <9>;
+       marvell,pad-type = "fixed-1-8v";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc_pins>;
+       status = "okay";
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+       mmccard: mmccard@0 {
+               compatible = "mmc-card";
+               reg = <0>;
+       };
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts
new file mode 100644 (file)
index 0000000..0f8405d
--- /dev/null
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7
+ * Copyright (C) 2018 Marvell
+ *
+ * Romain Perier <romain.perier@free-electrons.com>
+ * Konstantin Porotchkin <kostap@marvell.com>
+ *
+ */
+/*
+ * Schematic available at http://wiki.espressobin.net/tiki-download_file.php?fileId=200
+ */
+
+#include "armada-3720-espressobin.dtsi"
+
+/ {
+       model = "Globalscale Marvell ESPRESSOBin Board V7";
+       compatible = "globalscale,espressobin-v7", "globalscale,espressobin",
+                    "marvell,armada3720", "marvell,armada3710";
+};
+
+&switch0 {
+       ports {
+               port@1 {
+                       reg = <1>;
+                       label = "lan1";
+                       phy-handle = <&switch0phy0>;
+               };
+
+               port@3 {
+                       reg = <3>;
+                       label = "wan";
+                       phy-handle = <&switch0phy2>;
+               };
+       };
+};
index fbcf03f..1542d83 100644 (file)
 
 /dts-v1/;
 
-#include <dt-bindings/gpio/gpio.h>
-#include "armada-372x.dtsi"
+#include "armada-3720-espressobin.dtsi"
 
 / {
        model = "Globalscale Marvell ESPRESSOBin Board";
        compatible = "globalscale,espressobin", "marvell,armada3720", "marvell,armada3710";
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       memory@0 {
-               device_type = "memory";
-               reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
-       };
-
-       vcc_sd_reg1: regulator {
-               compatible = "regulator-gpio";
-               regulator-name = "vcc_sd1";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-boot-on;
-
-               gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>;
-               gpios-states = <0>;
-               states = <1800000 0x1
-                         3300000 0x0>;
-               enable-active-high;
-       };
-};
-
-/* J9 */
-&pcie0 {
-       status = "okay";
-       phys = <&comphy1 0>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>;
-};
-
-/* J6 */
-&sata {
-       status = "okay";
-       phys = <&comphy2 0>;
-       phy-names = "sata-phy";
-};
-
-/* J1 */
-&sdhci1 {
-       wp-inverted;
-       bus-width = <4>;
-       cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>;
-       marvell,pad-type = "sd";
-       vqmmc-supply = <&vcc_sd_reg1>;
-
-       pinctrl-names = "default";
-       pinctrl-0 = <&sdio_pins>;
-       status = "okay";
-};
-
-/* U11 */
-&sdhci0 {
-       non-removable;
-       bus-width = <8>;
-       mmc-ddr-1_8v;
-       mmc-hs400-1_8v;
-       marvell,xenon-emmc;
-       marvell,xenon-tun-count = <9>;
-       marvell,pad-type = "fixed-1-8v";
-
-       pinctrl-names = "default";
-       pinctrl-0 = <&mmc_pins>;
-/*
- * This eMMC is not populated on all boards, so disable it by
- * default and let the bootloader enable it, if it is present
- */
-       status = "disabled";
-};
-
-&spi0 {
-       status = "okay";
-
-       flash@0 {
-               reg = <0>;
-               compatible = "jedec,spi-nor";
-               spi-max-frequency = <104000000>;
-               m25p,fast-read;
-       };
-};
-
-/* Exported on the micro USB connector J5 through an FTDI */
-&uart0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart1_pins>;
-       status = "okay";
-};
-
-/*
- * Connector J17 and J18 expose a number of different features. Some pins are
- * multiplexed. This is the case for instance for the following features:
- * - UART1 (pin 24 = RX, pin 26 = TX). See armada-3720-db.dts for an example of
- *   how to enable it. Beware that the signals are 1.8V TTL.
- * - I2C
- * - SPI
- * - MMC
- */
-
-/* J7 */
-&usb3 {
-       status = "okay";
-};
-
-/* J8 */
-&usb2 {
-       status = "okay";
-};
-
-&mdio {
-       switch0: switch0@1 {
-               compatible = "marvell,mv88e6085";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               reg = <1>;
-
-               dsa,member = <0 0>;
-
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
-                               label = "cpu";
-                               ethernet = <&eth0>;
-                               phy-mode = "rgmii-id";
-                               fixed-link {
-                                       speed = <1000>;
-                                       full-duplex;
-                               };
-                       };
-
-                       port@1 {
-                               reg = <1>;
-                               label = "wan";
-                               phy-handle = <&switch0phy0>;
-                       };
-
-                       port@2 {
-                               reg = <2>;
-                               label = "lan0";
-                               phy-handle = <&switch0phy1>;
-                       };
-
-                       port@3 {
-                               reg = <3>;
-                               label = "lan1";
-                               phy-handle = <&switch0phy2>;
-                       };
-
-               };
-
-               mdio {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       switch0phy0: switch0phy0@11 {
-                               reg = <0x11>;
-                       };
-                       switch0phy1: switch0phy1@12 {
-                               reg = <0x12>;
-                       };
-                       switch0phy2: switch0phy2@13 {
-                               reg = <0x13>;
-                       };
-               };
-       };
-};
-
-&eth0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&rgmii_pins>, <&smi_pins>;
-       phy-mode = "rgmii-id";
-       status = "okay";
-
-       fixed-link {
-               speed = <1000>;
-               full-duplex;
-       };
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
new file mode 100644 (file)
index 0000000..53b8ac5
--- /dev/null
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board
+ * Copyright (C) 2016 Marvell
+ *
+ * Romain Perier <romain.perier@free-electrons.com>
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-372x.dtsi"
+
+/ {
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
+       };
+
+       vcc_sd_reg1: regulator {
+               compatible = "regulator-gpio";
+               regulator-name = "vcc_sd1";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+
+               gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>;
+               gpios-states = <0>;
+               states = <1800000 0x1
+                         3300000 0x0>;
+               enable-active-high;
+       };
+};
+
+/* J9 */
+&pcie0 {
+       status = "okay";
+       phys = <&comphy1 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>;
+};
+
+/* J6 */
+&sata {
+       status = "okay";
+       phys = <&comphy2 0>;
+       phy-names = "sata-phy";
+};
+
+/* J1 */
+&sdhci1 {
+       wp-inverted;
+       bus-width = <4>;
+       cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>;
+       marvell,pad-type = "sd";
+       vqmmc-supply = <&vcc_sd_reg1>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio_pins>;
+       status = "okay";
+};
+
+&spi0 {
+       status = "okay";
+
+       flash@0 {
+               reg = <0>;
+               compatible = "jedec,spi-nor";
+               spi-max-frequency = <104000000>;
+               m25p,fast-read;
+       };
+};
+
+/* Exported on the micro USB connector J5 through an FTDI */
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+       status = "okay";
+};
+
+/*
+ * Connector J17 and J18 expose a number of different features. Some pins are
+ * multiplexed. This is the case for instance for the following features:
+ * - UART1 (pin 24 = RX, pin 26 = TX). See armada-3720-db.dts for an example of
+ *   how to enable it. Beware that the signals are 1.8V TTL.
+ * - I2C
+ * - SPI
+ * - MMC
+ */
+
+/* J7 */
+&usb3 {
+       status = "okay";
+};
+
+/* J8 */
+&usb2 {
+       status = "okay";
+};
+
+&mdio {
+       switch0: switch0@1 {
+               compatible = "marvell,mv88e6085";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <1>;
+
+               dsa,member = <0 0>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               label = "cpu";
+                               ethernet = <&eth0>;
+                               phy-mode = "rgmii-id";
+                               fixed-link {
+                                       speed = <1000>;
+                                       full-duplex;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               label = "wan";
+                               phy-handle = <&switch0phy0>;
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               label = "lan0";
+                               phy-handle = <&switch0phy1>;
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               label = "lan1";
+                               phy-handle = <&switch0phy2>;
+                       };
+
+               };
+
+               mdio {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       switch0phy0: switch0phy0@11 {
+                               reg = <0x11>;
+                       };
+                       switch0phy1: switch0phy1@12 {
+                               reg = <0x12>;
+                       };
+                       switch0phy2: switch0phy2@13 {
+                               reg = <0x13>;
+                       };
+               };
+       };
+};
+
+&eth0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>, <&smi_pins>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+
+       fixed-link {
+               speed = <1000>;
+               full-duplex;
+       };
+};
index 5f350cc..bb42d1e 100644 (file)
                /* enabled by U-Boot if SFP module is present */
                status = "disabled";
        };
+
+       firmware {
+               turris-mox-rwtm {
+                       compatible = "cznic,turris-mox-rwtm";
+                       mboxes = <&rwtm 0>;
+                       status = "okay";
+               };
+       };
 };
 
 &i2c0 {
index e5c6d7c..293403a 100644 (file)
 /*
  * Instantiate the CP110
  */
-#define CP110_NAME             cp0
-#define CP110_BASE             f2000000
-#define CP110_PCIE_IO_BASE     0xf9000000
-#define CP110_PCIE_MEM_BASE    0xf6000000
-#define CP110_PCIE0_BASE       f2600000
-#define CP110_PCIE1_BASE       f2620000
-#define CP110_PCIE2_BASE       f2640000
+#define CP11X_NAME             cp0
+#define CP11X_BASE             f2000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xf6000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE       f2600000
+#define CP11X_PCIE1_BASE       f2620000
+#define CP11X_PCIE2_BASE       f2640000
 
 #include "armada-cp110.dtsi"
 
-#undef CP110_NAME
-#undef CP110_BASE
-#undef CP110_PCIE_IO_BASE
-#undef CP110_PCIE_MEM_BASE
-#undef CP110_PCIE0_BASE
-#undef CP110_PCIE1_BASE
-#undef CP110_PCIE2_BASE
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
 
 &cp0_gpio1 {
        status = "okay";
index d250f4b..572e261 100644 (file)
        num-lanes = <4>;
        num-viewport = <8>;
        reset-gpios = <&cp0_gpio2 20 GPIO_ACTIVE_LOW>;
-       ranges = <0x81000000 0x0 0xf9010000 0x0 0xf9010000 0x0 0x10000
-                 0x82000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x20000000>;
+       ranges = <0x82000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x20000000>;
        phys = <&cp0_comphy0 0>, <&cp0_comphy1 0>,
               <&cp0_comphy2 0>, <&cp0_comphy3 0>;
        phy-names = "cp0-pcie0-x4-lane0-phy", "cp0-pcie0-x4-lane1-phy",
index 8129b40..ee67c70 100644 (file)
 /*
  * Instantiate the master CP110
  */
-#define CP110_NAME             cp0
-#define CP110_BASE             f2000000
-#define CP110_PCIE_IO_BASE     0xf9000000
-#define CP110_PCIE_MEM_BASE    0xf6000000
-#define CP110_PCIE0_BASE       f2600000
-#define CP110_PCIE1_BASE       f2620000
-#define CP110_PCIE2_BASE       f2640000
+#define CP11X_NAME             cp0
+#define CP11X_BASE             f2000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xf6000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE       f2600000
+#define CP11X_PCIE1_BASE       f2620000
+#define CP11X_PCIE2_BASE       f2640000
 
 #include "armada-cp110.dtsi"
 
-#undef CP110_NAME
-#undef CP110_BASE
-#undef CP110_PCIE_IO_BASE
-#undef CP110_PCIE_MEM_BASE
-#undef CP110_PCIE0_BASE
-#undef CP110_PCIE1_BASE
-#undef CP110_PCIE2_BASE
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
 
 /*
  * Instantiate the slave CP110
  */
-#define CP110_NAME             cp1
-#define CP110_BASE             f4000000
-#define CP110_PCIE_IO_BASE     0xfd000000
-#define CP110_PCIE_MEM_BASE    0xfa000000
-#define CP110_PCIE0_BASE       f4600000
-#define CP110_PCIE1_BASE       f4620000
-#define CP110_PCIE2_BASE       f4640000
+#define CP11X_NAME             cp1
+#define CP11X_BASE             f4000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xfa000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE       f4600000
+#define CP11X_PCIE1_BASE       f4620000
+#define CP11X_PCIE2_BASE       f4640000
 
 #include "armada-cp110.dtsi"
 
-#undef CP110_NAME
-#undef CP110_BASE
-#undef CP110_PCIE_IO_BASE
-#undef CP110_PCIE_MEM_BASE
-#undef CP110_PCIE0_BASE
-#undef CP110_PCIE1_BASE
-#undef CP110_PCIE2_BASE
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
 
 /* The 80x0 has two CP blocks, but uses only one block from each. */
 &cp1_gpio1 {
index 9024a2d..0984955 100644 (file)
                        reg = <0x000>;
                        enable-method = "psci";
                        #cooling-cells = <2>;
+                       clocks = <&cpu_clk 0>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2>;
                };
                cpu1: cpu@1 {
                        device_type = "cpu";
                        reg = <0x001>;
                        enable-method = "psci";
                        #cooling-cells = <2>;
+                       clocks = <&cpu_clk 0>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2>;
+               };
+
+               l2: l2-cache {
+                       compatible = "cache";
+                       cache-size = <0x80000>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
                };
        };
 };
index c25bc65..3db4271 100644 (file)
                        enable-method = "psci";
                        #cooling-cells = <2>;
                        clocks = <&cpu_clk 0>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_0>;
                };
                cpu1: cpu@1 {
                        device_type = "cpu";
                        enable-method = "psci";
                        #cooling-cells = <2>;
                        clocks = <&cpu_clk 0>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_0>;
                };
                cpu2: cpu@100 {
                        device_type = "cpu";
                        enable-method = "psci";
                        #cooling-cells = <2>;
                        clocks = <&cpu_clk 1>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_1>;
                };
                cpu3: cpu@101 {
                        device_type = "cpu";
                        enable-method = "psci";
                        #cooling-cells = <2>;
                        clocks = <&cpu_clk 1>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_1>;
+               };
+
+               l2_0: l2-cache0 {
+                       compatible = "cache";
+                       cache-size = <0x80000>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+               };
+
+               l2_1: l2-cache1 {
+                       compatible = "cache";
+                       cache-size = <0x80000>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
                };
        };
 };
index d06dd19..8666286 100644 (file)
  * Device Tree file for Marvell Armada AP806.
  */
 
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/thermal/thermal.h>
-
-/dts-v1/;
+#define AP_NAME                ap806
+#include "armada-ap80x.dtsi"
 
 / {
        model = "Marvell Armada AP806";
        compatible = "marvell,armada-ap806";
-       #address-cells = <2>;
-       #size-cells = <2>;
-
-       aliases {
-               serial0 = &uart0;
-               serial1 = &uart1;
-               gpio0 = &ap_gpio;
-               spi0 = &spi0;
-       };
-
-       psci {
-               compatible = "arm,psci-0.2";
-               method = "smc";
-       };
-
-       reserved-memory {
-               #address-cells = <2>;
-               #size-cells = <2>;
-               ranges;
-
-               /*
-                * This area matches the mapping done with a
-                * mainline U-Boot, and should be updated by the
-                * bootloader.
-                */
-
-               psci-area@4000000 {
-                       reg = <0x0 0x4000000 0x0 0x200000>;
-                       no-map;
-               };
-       };
-
-       ap806 {
-               #address-cells = <2>;
-               #size-cells = <2>;
-               compatible = "simple-bus";
-               interrupt-parent = <&gic>;
-               ranges;
-
-               config-space@f0000000 {
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       compatible = "simple-bus";
-                       ranges = <0x0 0x0 0xf0000000 0x1000000>;
-
-                       gic: interrupt-controller@210000 {
-                               compatible = "arm,gic-400";
-                               #interrupt-cells = <3>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges;
-                               interrupt-controller;
-                               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-                               reg = <0x210000 0x10000>,
-                                     <0x220000 0x20000>,
-                                     <0x240000 0x20000>,
-                                     <0x260000 0x20000>;
-
-                               gic_v2m0: v2m@280000 {
-                                       compatible = "arm,gic-v2m-frame";
-                                       msi-controller;
-                                       reg = <0x280000 0x1000>;
-                                       arm,msi-base-spi = <160>;
-                                       arm,msi-num-spis = <32>;
-                               };
-                               gic_v2m1: v2m@290000 {
-                                       compatible = "arm,gic-v2m-frame";
-                                       msi-controller;
-                                       reg = <0x290000 0x1000>;
-                                       arm,msi-base-spi = <192>;
-                                       arm,msi-num-spis = <32>;
-                               };
-                               gic_v2m2: v2m@2a0000 {
-                                       compatible = "arm,gic-v2m-frame";
-                                       msi-controller;
-                                       reg = <0x2a0000 0x1000>;
-                                       arm,msi-base-spi = <224>;
-                                       arm,msi-num-spis = <32>;
-                               };
-                               gic_v2m3: v2m@2b0000 {
-                                       compatible = "arm,gic-v2m-frame";
-                                       msi-controller;
-                                       reg = <0x2b0000 0x1000>;
-                                       arm,msi-base-spi = <256>;
-                                       arm,msi-num-spis = <32>;
-                               };
-                       };
-
-                       timer {
-                               compatible = "arm,armv8-timer";
-                               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-                                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-                                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-                                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
-                       };
-
-                       pmu {
-                               compatible = "arm,cortex-a72-pmu";
-                               interrupt-parent = <&pic>;
-                               interrupts = <17>;
-                       };
-
-                       odmi: odmi@300000 {
-                               compatible = "marvell,odmi-controller";
-                               interrupt-controller;
-                               msi-controller;
-                               marvell,odmi-frames = <4>;
-                               reg = <0x300000 0x4000>,
-                                     <0x304000 0x4000>,
-                                     <0x308000 0x4000>,
-                                     <0x30C000 0x4000>;
-                               marvell,spi-base = <128>, <136>, <144>, <152>;
-                       };
-
-                       gicp: gicp@3f0040 {
-                               compatible = "marvell,ap806-gicp";
-                               reg = <0x3f0040 0x10>;
-                               marvell,spi-ranges = <64 64>, <288 64>;
-                               msi-controller;
-                       };
-
-                       pic: interrupt-controller@3f0100 {
-                               compatible = "marvell,armada-8k-pic";
-                               reg = <0x3f0100 0x10>;
-                               #interrupt-cells = <1>;
-                               interrupt-controller;
-                               interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-
-                       sei: interrupt-controller@3f0200 {
-                               compatible = "marvell,ap806-sei";
-                               reg = <0x3f0200 0x40>;
-                               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
-                               #interrupt-cells = <1>;
-                               interrupt-controller;
-                               msi-controller;
-                       };
-
-                       xor@400000 {
-                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
-                               reg = <0x400000 0x1000>,
-                                     <0x410000 0x1000>;
-                               msi-parent = <&gic_v2m0>;
-                               clocks = <&ap_clk 3>;
-                               dma-coherent;
-                       };
-
-                       xor@420000 {
-                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
-                               reg = <0x420000 0x1000>,
-                                     <0x430000 0x1000>;
-                               msi-parent = <&gic_v2m0>;
-                               clocks = <&ap_clk 3>;
-                               dma-coherent;
-                       };
-
-                       xor@440000 {
-                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
-                               reg = <0x440000 0x1000>,
-                                     <0x450000 0x1000>;
-                               msi-parent = <&gic_v2m0>;
-                               clocks = <&ap_clk 3>;
-                               dma-coherent;
-                       };
-
-                       xor@460000 {
-                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
-                               reg = <0x460000 0x1000>,
-                                     <0x470000 0x1000>;
-                               msi-parent = <&gic_v2m0>;
-                               clocks = <&ap_clk 3>;
-                               dma-coherent;
-                       };
-
-                       spi0: spi@510600 {
-                               compatible = "marvell,armada-380-spi";
-                               reg = <0x510600 0x50>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&ap_clk 3>;
-                               status = "disabled";
-                       };
-
-                       i2c0: i2c@511000 {
-                               compatible = "marvell,mv78230-i2c";
-                               reg = <0x511000 0x20>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
-                               timeout-ms = <1000>;
-                               clocks = <&ap_clk 3>;
-                               status = "disabled";
-                       };
-
-                       uart0: serial@512000 {
-                               compatible = "snps,dw-apb-uart";
-                               reg = <0x512000 0x100>;
-                               reg-shift = <2>;
-                               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-                               reg-io-width = <1>;
-                               clocks = <&ap_clk 3>;
-                               status = "disabled";
-                       };
-
-                       uart1: serial@512100 {
-                               compatible = "snps,dw-apb-uart";
-                               reg = <0x512100 0x100>;
-                               reg-shift = <2>;
-                               interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-                               reg-io-width = <1>;
-                               clocks = <&ap_clk 3>;
-                               status = "disabled";
-
-                       };
-
-                       watchdog: watchdog@610000 {
-                               compatible = "arm,sbsa-gwdt";
-                               reg = <0x610000 0x1000>, <0x600000 0x1000>;
-                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-
-                       ap_sdhci0: sdhci@6e0000 {
-                               compatible = "marvell,armada-ap806-sdhci";
-                               reg = <0x6e0000 0x300>;
-                               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
-                               clock-names = "core";
-                               clocks = <&ap_clk 4>;
-                               dma-coherent;
-                               marvell,xenon-phy-slow-mode;
-                               status = "disabled";
-                       };
-
-                       ap_syscon: system-controller@6f4000 {
-                               compatible = "syscon", "simple-mfd";
-                               reg = <0x6f4000 0x2000>;
-
-                               ap_clk: clock {
-                                       compatible = "marvell,ap806-clock";
-                                       #clock-cells = <1>;
-                               };
-
-                               ap_pinctrl: pinctrl {
-                                       compatible = "marvell,ap806-pinctrl";
-
-                                       uart0_pins: uart0-pins {
-                                               marvell,pins = "mpp11", "mpp19";
-                                               marvell,function = "uart0";
-                                       };
-                               };
-
-                               ap_gpio: gpio@1040 {
-                                       compatible = "marvell,armada-8k-gpio";
-                                       offset = <0x1040>;
-                                       ngpios = <20>;
-                                       gpio-controller;
-                                       #gpio-cells = <2>;
-                                       gpio-ranges = <&ap_pinctrl 0 0 20>;
-                               };
-                       };
-
-                       ap_syscon1: system-controller@6f8000 {
-                               compatible = "syscon", "simple-mfd";
-                               reg = <0x6f8000 0x1000>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-
-                               cpu_clk: clock-cpu@278 {
-                                       compatible = "marvell,ap806-cpu-clock";
-                                       clocks = <&ap_clk 0>, <&ap_clk 1>;
-                                       #clock-cells = <1>;
-                                       reg = <0x278 0xa30>;
-                               };
+};
 
-                               ap_thermal: thermal-sensor@80 {
-                                       compatible = "marvell,armada-ap806-thermal";
-                                       reg = <0x80 0x10>;
-                                       interrupt-parent = <&sei>;
-                                       interrupts = <18>;
-                                       #thermal-sensor-cells = <1>;
-                               };
-                       };
-               };
+&ap_syscon0 {
+       ap_clk: clock {
+               compatible = "marvell,ap806-clock";
+               #clock-cells = <1>;
        };
+};
 
-       /*
-        * The thermal IP features one internal sensor plus, if applicable, one
-        * remote channel wired to one sensor per CPU.
-        *
-        * Only one thermal zone per AP/CP may trigger interrupts at a time, the
-        * first one that will have a critical trip point will be chosen.
-        */
-       thermal-zones {
-               ap_thermal_ic: ap-thermal-ic {
-                       polling-delay-passive = <0>; /* Interrupt driven */
-                       polling-delay = <0>; /* Interrupt driven */
-
-                       thermal-sensors = <&ap_thermal 0>;
-
-                       trips {
-                               ap_crit: ap-crit {
-                                       temperature = <100000>; /* mC degrees */
-                                       hysteresis = <2000>; /* mC degrees */
-                                       type = "critical";
-                               };
-                       };
-
-                       cooling-maps { };
-               };
-
-               ap_thermal_cpu0: ap-thermal-cpu0 {
-                       polling-delay-passive = <1000>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&ap_thermal 1>;
-
-                       trips {
-                               cpu0_hot: cpu0-hot {
-                                       temperature = <85000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                               cpu0_emerg: cpu0-emerg {
-                                       temperature = <95000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                       };
-
-                       cooling-maps {
-                               map0_hot: map0-hot {
-                                       trip = <&cpu0_hot>;
-                                       cooling-device = <&cpu0 1 2>,
-                                               <&cpu1 1 2>;
-                               };
-                               map0_emerg: map0-ermerg {
-                                       trip = <&cpu0_emerg>;
-                                       cooling-device = <&cpu0 3 3>,
-                                               <&cpu1 3 3>;
-                               };
-                       };
-               };
-
-               ap_thermal_cpu1: ap-thermal-cpu1 {
-                       polling-delay-passive = <1000>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&ap_thermal 2>;
-
-                       trips {
-                               cpu1_hot: cpu1-hot {
-                                       temperature = <85000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                               cpu1_emerg: cpu1-emerg {
-                                       temperature = <95000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                       };
-
-                       cooling-maps {
-                               map1_hot: map1-hot {
-                                       trip = <&cpu1_hot>;
-                                       cooling-device = <&cpu0 1 2>,
-                                               <&cpu1 1 2>;
-                               };
-                               map1_emerg: map1-emerg {
-                                       trip = <&cpu1_emerg>;
-                                       cooling-device = <&cpu0 3 3>,
-                                               <&cpu1 3 3>;
-                               };
-                       };
-               };
-
-               ap_thermal_cpu2: ap-thermal-cpu2 {
-                       polling-delay-passive = <1000>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&ap_thermal 3>;
-
-                       trips {
-                               cpu2_hot: cpu2-hot {
-                                       temperature = <85000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                               cpu2_emerg: cpu2-emerg {
-                                       temperature = <95000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                       };
-
-                       cooling-maps {
-                               map2_hot: map2-hot {
-                                       trip = <&cpu2_hot>;
-                                       cooling-device = <&cpu2 1 2>,
-                                               <&cpu3 1 2>;
-                               };
-                               map2_emerg: map2-emerg {
-                                       trip = <&cpu2_emerg>;
-                                       cooling-device = <&cpu2 3 3>,
-                                               <&cpu3 3 3>;
-                               };
-                       };
-               };
-
-               ap_thermal_cpu3: ap-thermal-cpu3 {
-                       polling-delay-passive = <1000>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&ap_thermal 4>;
-
-                       trips {
-                               cpu3_hot: cpu3-hot {
-                                       temperature = <85000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                               cpu3_emerg: cpu3-emerg {
-                                       temperature = <95000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
-                       };
-
-                       cooling-maps {
-                               map3_hot: map3-bhot {
-                                       trip = <&cpu3_hot>;
-                                       cooling-device = <&cpu2 1 2>,
-                                               <&cpu3 1 2>;
-                               };
-                               map3_emerg: map3-emerg {
-                                       trip = <&cpu3_emerg>;
-                                       cooling-device = <&cpu2 3 3>,
-                                               <&cpu3 3 3>;
-                               };
-                       };
-               };
+&ap_syscon1 {
+       cpu_clk: clock-cpu@278 {
+               compatible = "marvell,ap806-cpu-clock";
+               clocks = <&ap_clk 0>, <&ap_clk 1>;
+               #clock-cells = <1>;
+               reg = <0x278 0xa30>;
        };
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-ap807-quad.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807-quad.dtsi
new file mode 100644 (file)
index 0000000..840466e
--- /dev/null
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Marvell Armada AP807 Quad
+ *
+ * Copyright (C) 2019 Marvell Technology Group Ltd.
+ */
+
+#include "armada-ap807.dtsi"
+
+/ {
+       model = "Marvell Armada AP807 Quad";
+       compatible = "marvell,armada-ap807-quad", "marvell,armada-ap807";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0x000>;
+                       enable-method = "psci";
+                       #cooling-cells = <2>;
+                       clocks = <&cpu_clk 0>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_0>;
+               };
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0x001>;
+                       enable-method = "psci";
+                       #cooling-cells = <2>;
+                       clocks = <&cpu_clk 0>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_0>;
+               };
+               cpu2: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0x100>;
+                       enable-method = "psci";
+                       #cooling-cells = <2>;
+                       clocks = <&cpu_clk 1>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_1>;
+               };
+               cpu3: cpu@101 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0x101>;
+                       enable-method = "psci";
+                       #cooling-cells = <2>;
+                       clocks = <&cpu_clk 1>;
+                       i-cache-size = <0xc000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2_1>;
+               };
+
+               l2_0: l2-cache0 {
+                       compatible = "cache";
+                       cache-size = <0x80000>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+               };
+
+               l2_1: l2-cache1 {
+                       compatible = "cache";
+                       cache-size = <0x80000>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
new file mode 100644 (file)
index 0000000..623010f
--- /dev/null
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Marvell Armada AP807
+ *
+ * Copyright (C) 2019 Marvell Technology Group Ltd.
+ */
+
+#define AP_NAME                ap807
+#include "armada-ap80x.dtsi"
+
+/ {
+       model = "Marvell Armada AP807";
+       compatible = "marvell,armada-ap807";
+};
+
+&ap_syscon0 {
+       ap_clk: clock {
+               compatible = "marvell,ap807-clock";
+               #clock-cells = <1>;
+       };
+};
+
+&ap_syscon1 {
+       cpu_clk: clock-cpu {
+               compatible = "marvell,ap807-cpu-clock";
+               clocks = <&ap_clk 0>, <&ap_clk 1>;
+               #clock-cells = <1>;
+       };
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi b/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi
new file mode 100644 (file)
index 0000000..e7438c2
--- /dev/null
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Marvell Technology Group Ltd.
+ *
+ * Device Tree file for Marvell Armada AP80x.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/dts-v1/;
+
+/ {
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               gpio0 = &ap_gpio;
+               spi0 = &spi0;
+       };
+
+       psci {
+               compatible = "arm,psci-0.2";
+               method = "smc";
+       };
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               /*
+                * This area matches the mapping done with a
+                * mainline U-Boot, and should be updated by the
+                * bootloader.
+                */
+
+               psci-area@4000000 {
+                       reg = <0x0 0x4000000 0x0 0x200000>;
+                       no-map;
+               };
+       };
+
+       AP_NAME {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "simple-bus";
+               interrupt-parent = <&gic>;
+               ranges;
+
+               config-space@f0000000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       ranges = <0x0 0x0 0xf0000000 0x1000000>;
+
+                       gic: interrupt-controller@210000 {
+                               compatible = "arm,gic-400";
+                               #interrupt-cells = <3>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges;
+                               interrupt-controller;
+                               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+                               reg = <0x210000 0x10000>,
+                                     <0x220000 0x20000>,
+                                     <0x240000 0x20000>,
+                                     <0x260000 0x20000>;
+
+                               gic_v2m0: v2m@280000 {
+                                       compatible = "arm,gic-v2m-frame";
+                                       msi-controller;
+                                       reg = <0x280000 0x1000>;
+                                       arm,msi-base-spi = <160>;
+                                       arm,msi-num-spis = <32>;
+                               };
+                               gic_v2m1: v2m@290000 {
+                                       compatible = "arm,gic-v2m-frame";
+                                       msi-controller;
+                                       reg = <0x290000 0x1000>;
+                                       arm,msi-base-spi = <192>;
+                                       arm,msi-num-spis = <32>;
+                               };
+                               gic_v2m2: v2m@2a0000 {
+                                       compatible = "arm,gic-v2m-frame";
+                                       msi-controller;
+                                       reg = <0x2a0000 0x1000>;
+                                       arm,msi-base-spi = <224>;
+                                       arm,msi-num-spis = <32>;
+                               };
+                               gic_v2m3: v2m@2b0000 {
+                                       compatible = "arm,gic-v2m-frame";
+                                       msi-controller;
+                                       reg = <0x2b0000 0x1000>;
+                                       arm,msi-base-spi = <256>;
+                                       arm,msi-num-spis = <32>;
+                               };
+                       };
+
+                       timer {
+                               compatible = "arm,armv8-timer";
+                               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+                       };
+
+                       pmu {
+                               compatible = "arm,cortex-a72-pmu";
+                               interrupt-parent = <&pic>;
+                               interrupts = <17>;
+                       };
+
+                       odmi: odmi@300000 {
+                               compatible = "marvell,odmi-controller";
+                               interrupt-controller;
+                               msi-controller;
+                               marvell,odmi-frames = <4>;
+                               reg = <0x300000 0x4000>,
+                                     <0x304000 0x4000>,
+                                     <0x308000 0x4000>,
+                                     <0x30C000 0x4000>;
+                               marvell,spi-base = <128>, <136>, <144>, <152>;
+                       };
+
+                       gicp: gicp@3f0040 {
+                               compatible = "marvell,ap806-gicp";
+                               reg = <0x3f0040 0x10>;
+                               marvell,spi-ranges = <64 64>, <288 64>;
+                               msi-controller;
+                       };
+
+                       pic: interrupt-controller@3f0100 {
+                               compatible = "marvell,armada-8k-pic";
+                               reg = <0x3f0100 0x10>;
+                               #interrupt-cells = <1>;
+                               interrupt-controller;
+                               interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       sei: interrupt-controller@3f0200 {
+                               compatible = "marvell,ap806-sei";
+                               reg = <0x3f0200 0x40>;
+                               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+                               #interrupt-cells = <1>;
+                               interrupt-controller;
+                               msi-controller;
+                       };
+
+                       xor@400000 {
+                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+                               reg = <0x400000 0x1000>,
+                                     <0x410000 0x1000>;
+                               msi-parent = <&gic_v2m0>;
+                               clocks = <&ap_clk 3>;
+                               dma-coherent;
+                       };
+
+                       xor@420000 {
+                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+                               reg = <0x420000 0x1000>,
+                                     <0x430000 0x1000>;
+                               msi-parent = <&gic_v2m0>;
+                               clocks = <&ap_clk 3>;
+                               dma-coherent;
+                       };
+
+                       xor@440000 {
+                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+                               reg = <0x440000 0x1000>,
+                                     <0x450000 0x1000>;
+                               msi-parent = <&gic_v2m0>;
+                               clocks = <&ap_clk 3>;
+                               dma-coherent;
+                       };
+
+                       xor@460000 {
+                               compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+                               reg = <0x460000 0x1000>,
+                                     <0x470000 0x1000>;
+                               msi-parent = <&gic_v2m0>;
+                               clocks = <&ap_clk 3>;
+                               dma-coherent;
+                       };
+
+                       spi0: spi@510600 {
+                               compatible = "marvell,armada-380-spi";
+                               reg = <0x510600 0x50>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&ap_clk 3>;
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c@511000 {
+                               compatible = "marvell,mv78230-i2c";
+                               reg = <0x511000 0x20>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                               timeout-ms = <1000>;
+                               clocks = <&ap_clk 3>;
+                               status = "disabled";
+                       };
+
+                       uart0: serial@512000 {
+                               compatible = "snps,dw-apb-uart";
+                               reg = <0x512000 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                               reg-io-width = <1>;
+                               clocks = <&ap_clk 3>;
+                               status = "disabled";
+                       };
+
+                       uart1: serial@512100 {
+                               compatible = "snps,dw-apb-uart";
+                               reg = <0x512100 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               reg-io-width = <1>;
+                               clocks = <&ap_clk 3>;
+                               status = "disabled";
+
+                       };
+
+                       watchdog: watchdog@610000 {
+                               compatible = "arm,sbsa-gwdt";
+                               reg = <0x610000 0x1000>, <0x600000 0x1000>;
+                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       ap_sdhci0: sdhci@6e0000 {
+                               compatible = "marvell,armada-ap806-sdhci";
+                               reg = <0x6e0000 0x300>;
+                               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+                               clock-names = "core";
+                               clocks = <&ap_clk 4>;
+                               dma-coherent;
+                               marvell,xenon-phy-slow-mode;
+                               status = "disabled";
+                       };
+
+                       ap_syscon0: system-controller@6f4000 {
+                               compatible = "syscon", "simple-mfd";
+                               reg = <0x6f4000 0x2000>;
+
+                               ap_pinctrl: pinctrl {
+                                       compatible = "marvell,ap806-pinctrl";
+
+                                       uart0_pins: uart0-pins {
+                                               marvell,pins = "mpp11", "mpp19";
+                                               marvell,function = "uart0";
+                                       };
+                               };
+
+                               ap_gpio: gpio@1040 {
+                                       compatible = "marvell,armada-8k-gpio";
+                                       offset = <0x1040>;
+                                       ngpios = <20>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       gpio-ranges = <&ap_pinctrl 0 0 20>;
+                               };
+                       };
+
+                       ap_syscon1: system-controller@6f8000 {
+                               compatible = "syscon", "simple-mfd";
+                               reg = <0x6f8000 0x1000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               ap_thermal: thermal-sensor@80 {
+                                       compatible = "marvell,armada-ap806-thermal";
+                                       reg = <0x80 0x10>;
+                                       interrupt-parent = <&sei>;
+                                       interrupts = <18>;
+                                       #thermal-sensor-cells = <1>;
+                               };
+                       };
+               };
+       };
+
+       /*
+        * The thermal IP features one internal sensor plus, if applicable, one
+        * remote channel wired to one sensor per CPU.
+        *
+        * Only one thermal zone per AP/CP may trigger interrupts at a time, the
+        * first one that will have a critical trip point will be chosen.
+        */
+       thermal-zones {
+               ap_thermal_ic: ap-thermal-ic {
+                       polling-delay-passive = <0>; /* Interrupt driven */
+                       polling-delay = <0>; /* Interrupt driven */
+
+                       thermal-sensors = <&ap_thermal 0>;
+
+                       trips {
+                               ap_crit: ap-crit {
+                                       temperature = <100000>; /* mC degrees */
+                                       hysteresis = <2000>; /* mC degrees */
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps { };
+               };
+
+               ap_thermal_cpu0: ap-thermal-cpu0 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 1>;
+
+                       trips {
+                               cpu0_hot: cpu0-hot {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               cpu0_emerg: cpu0-emerg {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0_hot: map0-hot {
+                                       trip = <&cpu0_hot>;
+                                       cooling-device = <&cpu0 1 2>,
+                                               <&cpu1 1 2>;
+                               };
+                               map0_emerg: map0-ermerg {
+                                       trip = <&cpu0_emerg>;
+                                       cooling-device = <&cpu0 3 3>,
+                                               <&cpu1 3 3>;
+                               };
+                       };
+               };
+
+               ap_thermal_cpu1: ap-thermal-cpu1 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 2>;
+
+                       trips {
+                               cpu1_hot: cpu1-hot {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               cpu1_emerg: cpu1-emerg {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                       };
+
+                       cooling-maps {
+                               map1_hot: map1-hot {
+                                       trip = <&cpu1_hot>;
+                                       cooling-device = <&cpu0 1 2>,
+                                               <&cpu1 1 2>;
+                               };
+                               map1_emerg: map1-emerg {
+                                       trip = <&cpu1_emerg>;
+                                       cooling-device = <&cpu0 3 3>,
+                                               <&cpu1 3 3>;
+                               };
+                       };
+               };
+
+               ap_thermal_cpu2: ap-thermal-cpu2 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 3>;
+
+                       trips {
+                               cpu2_hot: cpu2-hot {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               cpu2_emerg: cpu2-emerg {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                       };
+
+                       cooling-maps {
+                               map2_hot: map2-hot {
+                                       trip = <&cpu2_hot>;
+                                       cooling-device = <&cpu2 1 2>,
+                                               <&cpu3 1 2>;
+                               };
+                               map2_emerg: map2-emerg {
+                                       trip = <&cpu2_emerg>;
+                                       cooling-device = <&cpu2 3 3>,
+                                               <&cpu3 3 3>;
+                               };
+                       };
+               };
+
+               ap_thermal_cpu3: ap-thermal-cpu3 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 4>;
+
+                       trips {
+                               cpu3_hot: cpu3-hot {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               cpu3_emerg: cpu3-emerg {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                       };
+
+                       cooling-maps {
+                               map3_hot: map3-bhot {
+                                       trip = <&cpu3_hot>;
+                                       cooling-device = <&cpu2 1 2>,
+                                               <&cpu3 1 2>;
+                               };
+                               map3_emerg: map3-emerg {
+                                       trip = <&cpu3_emerg>;
+                                       cooling-device = <&cpu2 3 3>,
+                                               <&cpu3 3 3>;
+                               };
+                       };
+               };
+       };
+};
index b29c640..c04c6c4 100644 (file)
@@ -6,6 +6,6 @@
 /* Common definitions used by Armada 7K/8K DTs */
 #define PASTER(x, y) x ## y
 #define EVALUATOR(x, y) PASTER(x, y)
-#define CP110_LABEL(name) EVALUATOR(CP110_NAME, EVALUATOR(_, name))
-#define CP110_NODE_NAME(name) EVALUATOR(CP110_NAME, EVALUATOR(-, name))
+#define CP11X_LABEL(name) EVALUATOR(CP11X_NAME, EVALUATOR(_, name))
+#define CP11X_NODE_NAME(name) EVALUATOR(CP11X_NAME, EVALUATOR(-, name))
 #define ADDRESSIFY(addr) EVALUATOR(0x, addr)
index d819449..4fd33b0 100644 (file)
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
- * Copyright (C) 2016 Marvell Technology Group Ltd.
+ * Copyright (C) 2019 Marvell Technology Group Ltd.
  *
  * Device Tree file for Marvell Armada CP110.
  */
 
-#include <dt-bindings/interrupt-controller/mvebu-icu.h>
-#include <dt-bindings/thermal/thermal.h>
+#define CP11X_TYPE cp110
 
-#include "armada-common.dtsi"
+#include "armada-cp11x.dtsi"
 
-#define CP110_PCIEx_IO_BASE(iface)     (CP110_PCIE_IO_BASE + (iface *  0x10000))
-#define CP110_PCIEx_MEM_BASE(iface)    (CP110_PCIE_MEM_BASE + (iface *  0x1000000))
-#define CP110_PCIEx_CONF_BASE(iface)   (CP110_PCIEx_MEM_BASE(iface) + 0xf00000)
-
-/ {
-       /*
-        * The contents of the node are defined below, in order to
-        * save one indentation level
-        */
-       CP110_NAME: CP110_NAME { };
-
-       /*
-        * CPs only have one sensor in the thermal IC.
-        *
-        * The cooling maps are empty as there are no cooling devices.
-        */
-       thermal-zones {
-               CP110_LABEL(thermal_ic): CP110_NODE_NAME(thermal-ic) {
-                       polling-delay-passive = <0>; /* Interrupt driven */
-                       polling-delay = <0>; /* Interrupt driven */
-
-                       thermal-sensors = <&CP110_LABEL(thermal) 0>;
-
-                       trips {
-                               CP110_LABEL(crit): crit {
-                                       temperature = <100000>; /* mC degrees */
-                                       hysteresis = <2000>; /* mC degrees */
-                                       type = "critical";
-                               };
-                       };
-
-                       cooling-maps { };
-               };
-       };
-};
-
-&CP110_NAME {
-       #address-cells = <2>;
-       #size-cells = <2>;
-       compatible = "simple-bus";
-       interrupt-parent = <&CP110_LABEL(icu_nsr)>;
-       ranges;
-
-       config-space@CP110_BASE {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               compatible = "simple-bus";
-               ranges = <0x0 0x0 ADDRESSIFY(CP110_BASE) 0x2000000>;
-
-               CP110_LABEL(ethernet): ethernet@0 {
-                       compatible = "marvell,armada-7k-pp22";
-                       reg = <0x0 0x100000>, <0x129000 0xb000>;
-                       clocks = <&CP110_LABEL(clk) 1 3>, <&CP110_LABEL(clk) 1 9>,
-                                <&CP110_LABEL(clk) 1 5>, <&CP110_LABEL(clk) 1 6>,
-                                <&CP110_LABEL(clk) 1 18>;
-                       clock-names = "pp_clk", "gop_clk",
-                                     "mg_clk", "mg_core_clk", "axi_clk";
-                       marvell,system-controller = <&CP110_LABEL(syscon0)>;
-                       status = "disabled";
-                       dma-coherent;
-
-                       CP110_LABEL(eth0): eth0 {
-                               interrupts = <39 IRQ_TYPE_LEVEL_HIGH>,
-                                       <43 IRQ_TYPE_LEVEL_HIGH>,
-                                       <47 IRQ_TYPE_LEVEL_HIGH>,
-                                       <51 IRQ_TYPE_LEVEL_HIGH>,
-                                       <55 IRQ_TYPE_LEVEL_HIGH>,
-                                       <59 IRQ_TYPE_LEVEL_HIGH>,
-                                       <63 IRQ_TYPE_LEVEL_HIGH>,
-                                       <67 IRQ_TYPE_LEVEL_HIGH>,
-                                       <71 IRQ_TYPE_LEVEL_HIGH>,
-                                       <129 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "hif0", "hif1", "hif2",
-                                       "hif3", "hif4", "hif5", "hif6", "hif7",
-                                       "hif8", "link";
-                               port-id = <0>;
-                               gop-port-id = <0>;
-                               status = "disabled";
-                       };
-
-                       CP110_LABEL(eth1): eth1 {
-                               interrupts = <40 IRQ_TYPE_LEVEL_HIGH>,
-                                       <44 IRQ_TYPE_LEVEL_HIGH>,
-                                       <48 IRQ_TYPE_LEVEL_HIGH>,
-                                       <52 IRQ_TYPE_LEVEL_HIGH>,
-                                       <56 IRQ_TYPE_LEVEL_HIGH>,
-                                       <60 IRQ_TYPE_LEVEL_HIGH>,
-                                       <64 IRQ_TYPE_LEVEL_HIGH>,
-                                       <68 IRQ_TYPE_LEVEL_HIGH>,
-                                       <72 IRQ_TYPE_LEVEL_HIGH>,
-                                       <128 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "hif0", "hif1", "hif2",
-                                       "hif3", "hif4", "hif5", "hif6", "hif7",
-                                       "hif8", "link";
-                               port-id = <1>;
-                               gop-port-id = <2>;
-                               status = "disabled";
-                       };
-
-                       CP110_LABEL(eth2): eth2 {
-                               interrupts = <41 IRQ_TYPE_LEVEL_HIGH>,
-                                       <45 IRQ_TYPE_LEVEL_HIGH>,
-                                       <49 IRQ_TYPE_LEVEL_HIGH>,
-                                       <53 IRQ_TYPE_LEVEL_HIGH>,
-                                       <57 IRQ_TYPE_LEVEL_HIGH>,
-                                       <61 IRQ_TYPE_LEVEL_HIGH>,
-                                       <65 IRQ_TYPE_LEVEL_HIGH>,
-                                       <69 IRQ_TYPE_LEVEL_HIGH>,
-                                       <73 IRQ_TYPE_LEVEL_HIGH>,
-                                       <127 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "hif0", "hif1", "hif2",
-                                       "hif3", "hif4", "hif5", "hif6", "hif7",
-                                       "hif8", "link";
-                               port-id = <2>;
-                               gop-port-id = <3>;
-                               status = "disabled";
-                       };
-               };
-
-               CP110_LABEL(comphy): phy@120000 {
-                       compatible = "marvell,comphy-cp110";
-                       reg = <0x120000 0x6000>;
-                       marvell,system-controller = <&CP110_LABEL(syscon0)>;
-                       clocks = <&CP110_LABEL(clk) 1 5>, <&CP110_LABEL(clk) 1 6>,
-                                <&CP110_LABEL(clk) 1 18>;
-                       clock-names = "mg_clk", "mg_core_clk", "axi_clk";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       CP110_LABEL(comphy0): phy@0 {
-                               reg = <0>;
-                               #phy-cells = <1>;
-                       };
-
-                       CP110_LABEL(comphy1): phy@1 {
-                               reg = <1>;
-                               #phy-cells = <1>;
-                       };
-
-                       CP110_LABEL(comphy2): phy@2 {
-                               reg = <2>;
-                               #phy-cells = <1>;
-                       };
-
-                       CP110_LABEL(comphy3): phy@3 {
-                               reg = <3>;
-                               #phy-cells = <1>;
-                       };
-
-                       CP110_LABEL(comphy4): phy@4 {
-                               reg = <4>;
-                               #phy-cells = <1>;
-                       };
-
-                       CP110_LABEL(comphy5): phy@5 {
-                               reg = <5>;
-                               #phy-cells = <1>;
-                       };
-               };
-
-               CP110_LABEL(mdio): mdio@12a200 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "marvell,orion-mdio";
-                       reg = <0x12a200 0x10>;
-                       clocks = <&CP110_LABEL(clk) 1 9>, <&CP110_LABEL(clk) 1 5>,
-                                <&CP110_LABEL(clk) 1 6>, <&CP110_LABEL(clk) 1 18>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(xmdio): mdio@12a600 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "marvell,xmdio";
-                       reg = <0x12a600 0x10>;
-                       clocks = <&CP110_LABEL(clk) 1 5>,
-                                <&CP110_LABEL(clk) 1 6>, <&CP110_LABEL(clk) 1 18>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(icu): interrupt-controller@1e0000 {
-                       compatible = "marvell,cp110-icu";
-                       reg = <0x1e0000 0x440>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-
-                       CP110_LABEL(icu_nsr): interrupt-controller@10 {
-                               compatible = "marvell,cp110-icu-nsr";
-                               reg = <0x10 0x20>;
-                               #interrupt-cells = <2>;
-                               interrupt-controller;
-                               msi-parent = <&gicp>;
-                       };
-
-                       CP110_LABEL(icu_sei): interrupt-controller@50 {
-                               compatible = "marvell,cp110-icu-sei";
-                               reg = <0x50 0x10>;
-                               #interrupt-cells = <2>;
-                               interrupt-controller;
-                               msi-parent = <&sei>;
-                       };
-               };
-
-               CP110_LABEL(rtc): rtc@284000 {
-                       compatible = "marvell,armada-8k-rtc";
-                       reg = <0x284000 0x20>, <0x284080 0x24>;
-                       reg-names = "rtc", "rtc-soc";
-                       interrupts = <77 IRQ_TYPE_LEVEL_HIGH>;
-               };
-
-               CP110_LABEL(syscon0): system-controller@440000 {
-                       compatible = "syscon", "simple-mfd";
-                       reg = <0x440000 0x2000>;
-
-                       CP110_LABEL(clk): clock {
-                               compatible = "marvell,cp110-clock";
-                               #clock-cells = <2>;
-                       };
-
-                       CP110_LABEL(gpio1): gpio@100 {
-                               compatible = "marvell,armada-8k-gpio";
-                               offset = <0x100>;
-                               ngpios = <32>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               gpio-ranges = <&CP110_LABEL(pinctrl) 0 0 32>;
-                               interrupt-controller;
-                               interrupts = <86 IRQ_TYPE_LEVEL_HIGH>,
-                                       <85 IRQ_TYPE_LEVEL_HIGH>,
-                                       <84 IRQ_TYPE_LEVEL_HIGH>,
-                                       <83 IRQ_TYPE_LEVEL_HIGH>;
-                               #interrupt-cells = <2>;
-                               status = "disabled";
-                       };
-
-                       CP110_LABEL(gpio2): gpio@140 {
-                               compatible = "marvell,armada-8k-gpio";
-                               offset = <0x140>;
-                               ngpios = <31>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               gpio-ranges = <&CP110_LABEL(pinctrl) 0 32 31>;
-                               interrupt-controller;
-                               interrupts = <82 IRQ_TYPE_LEVEL_HIGH>,
-                                       <81 IRQ_TYPE_LEVEL_HIGH>,
-                                       <80 IRQ_TYPE_LEVEL_HIGH>,
-                                       <79 IRQ_TYPE_LEVEL_HIGH>;
-                               #interrupt-cells = <2>;
-                               status = "disabled";
-                       };
-               };
-
-               CP110_LABEL(syscon1): system-controller@400000 {
-                       compatible = "syscon", "simple-mfd";
-                       reg = <0x400000 0x1000>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-
-                       CP110_LABEL(thermal): thermal-sensor@70 {
-                               compatible = "marvell,armada-cp110-thermal";
-                               reg = <0x70 0x10>;
-                               interrupts-extended =
-                                       <&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>;
-                               #thermal-sensor-cells = <1>;
-                       };
-               };
-
-               CP110_LABEL(usb3_0): usb3@500000 {
-                       compatible = "marvell,armada-8k-xhci",
-                       "generic-xhci";
-                       reg = <0x500000 0x4000>;
-                       dma-coherent;
-                       interrupts = <106 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 22>,
-                                <&CP110_LABEL(clk) 1 16>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(usb3_1): usb3@510000 {
-                       compatible = "marvell,armada-8k-xhci",
-                       "generic-xhci";
-                       reg = <0x510000 0x4000>;
-                       dma-coherent;
-                       interrupts = <105 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 23>,
-                                <&CP110_LABEL(clk) 1 16>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(sata0): sata@540000 {
-                       compatible = "marvell,armada-8k-ahci",
-                       "generic-ahci";
-                       reg = <0x540000 0x30000>;
-                       dma-coherent;
-                       interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&CP110_LABEL(clk) 1 15>,
-                                <&CP110_LABEL(clk) 1 16>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-
-                       sata-port@0 {
-                               reg = <0>;
-                       };
-
-                       sata-port@1 {
-                               reg = <1>;
-                       };
-               };
-
-               CP110_LABEL(xor0): xor@6a0000 {
-                       compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
-                       reg = <0x6a0000 0x1000>, <0x6b0000 0x1000>;
-                       dma-coherent;
-                       msi-parent = <&gic_v2m0>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 8>,
-                                <&CP110_LABEL(clk) 1 14>;
-               };
-
-               CP110_LABEL(xor1): xor@6c0000 {
-                       compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
-                       reg = <0x6c0000 0x1000>, <0x6d0000 0x1000>;
-                       dma-coherent;
-                       msi-parent = <&gic_v2m0>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 7>,
-                                <&CP110_LABEL(clk) 1 14>;
-               };
-
-               CP110_LABEL(spi0): spi@700600 {
-                       compatible = "marvell,armada-380-spi";
-                       reg = <0x700600 0x50>;
-                       #address-cells = <0x1>;
-                       #size-cells = <0x0>;
-                       clock-names = "core", "axi";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(spi1): spi@700680 {
-                       compatible = "marvell,armada-380-spi";
-                       reg = <0x700680 0x50>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       clock-names = "core", "axi";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(i2c0): i2c@701000 {
-                       compatible = "marvell,mv78230-i2c";
-                       reg = <0x701000 0x20>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(i2c1): i2c@701100 {
-                       compatible = "marvell,mv78230-i2c";
-                       reg = <0x701100 0x20>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(uart0): serial@702000 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x702000 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-io-width = <1>;
-                       clock-names = "baudclk", "apb_pclk";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(uart1): serial@702100 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x702100 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-io-width = <1>;
-                       clock-names = "baudclk", "apb_pclk";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(uart2): serial@702200 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x702200 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-io-width = <1>;
-                       clock-names = "baudclk", "apb_pclk";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(uart3): serial@702300 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x702300 0x100>;
-                       reg-shift = <2>;
-                       interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-io-width = <1>;
-                       clock-names = "baudclk", "apb_pclk";
-                       clocks = <&CP110_LABEL(clk) 1 21>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(nand_controller): nand@720000 {
-                       /*
-                       * Due to the limitation of the pins available
-                       * this controller is only usable on the CPM
-                       * for A7K and on the CPS for A8K.
-                       */
-                       compatible = "marvell,armada-8k-nand-controller",
-                               "marvell,armada370-nand-controller";
-                       reg = <0x720000 0x54>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <115 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 2>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       marvell,system-controller = <&CP110_LABEL(syscon0)>;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(trng): trng@760000 {
-                       compatible = "marvell,armada-8k-rng",
-                       "inside-secure,safexcel-eip76";
-                       reg = <0x760000 0x7d>;
-                       interrupts = <95 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 25>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       status = "okay";
-               };
-
-               CP110_LABEL(sdhci0): sdhci@780000 {
-                       compatible = "marvell,armada-cp110-sdhci";
-                       reg = <0x780000 0x300>;
-                       interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-names = "core", "axi";
-                       clocks = <&CP110_LABEL(clk) 1 4>, <&CP110_LABEL(clk) 1 18>;
-                       dma-coherent;
-                       status = "disabled";
-               };
-
-               CP110_LABEL(crypto): crypto@800000 {
-                       compatible = "inside-secure,safexcel-eip197b";
-                       reg = <0x800000 0x200000>;
-                       interrupts = <87 IRQ_TYPE_LEVEL_HIGH>,
-                               <88 IRQ_TYPE_LEVEL_HIGH>,
-                               <89 IRQ_TYPE_LEVEL_HIGH>,
-                               <90 IRQ_TYPE_LEVEL_HIGH>,
-                               <91 IRQ_TYPE_LEVEL_HIGH>,
-                               <92 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "mem", "ring0", "ring1",
-                               "ring2", "ring3", "eip";
-                       clock-names = "core", "reg";
-                       clocks = <&CP110_LABEL(clk) 1 26>,
-                                <&CP110_LABEL(clk) 1 17>;
-                       dma-coherent;
-               };
-       };
-
-       CP110_LABEL(pcie0): pcie@CP110_PCIE0_BASE {
-               compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
-               reg = <0 ADDRESSIFY(CP110_PCIE0_BASE) 0 0x10000>,
-                     <0 CP110_PCIEx_CONF_BASE(0) 0 0x80000>;
-               reg-names = "ctrl", "config";
-               #address-cells = <3>;
-               #size-cells = <2>;
-               #interrupt-cells = <1>;
-               device_type = "pci";
-               dma-coherent;
-               msi-parent = <&gic_v2m0>;
-
-               bus-range = <0 0xff>;
-               ranges =
-               /* downstream I/O */
-               <0x81000000 0 CP110_PCIEx_IO_BASE(0) 0  CP110_PCIEx_IO_BASE(0) 0 0x10000
-               /* non-prefetchable memory */
-               0x82000000 0 CP110_PCIEx_MEM_BASE(0) 0  CP110_PCIEx_MEM_BASE(0) 0 0xf00000>;
-               interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &CP110_LABEL(icu_nsr) 22 IRQ_TYPE_LEVEL_HIGH>;
-               interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
-               num-lanes = <1>;
-               clock-names = "core", "reg";
-               clocks = <&CP110_LABEL(clk) 1 13>, <&CP110_LABEL(clk) 1 14>;
-               status = "disabled";
-       };
-
-       CP110_LABEL(pcie1): pcie@CP110_PCIE1_BASE {
-               compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
-               reg = <0 ADDRESSIFY(CP110_PCIE1_BASE) 0 0x10000>,
-                     <0 CP110_PCIEx_CONF_BASE(1) 0 0x80000>;
-               reg-names = "ctrl", "config";
-               #address-cells = <3>;
-               #size-cells = <2>;
-               #interrupt-cells = <1>;
-               device_type = "pci";
-               dma-coherent;
-               msi-parent = <&gic_v2m0>;
-
-               bus-range = <0 0xff>;
-               ranges =
-               /* downstream I/O */
-               <0x81000000 0 CP110_PCIEx_IO_BASE(1) 0  CP110_PCIEx_IO_BASE(1) 0 0x10000
-               /* non-prefetchable memory */
-               0x82000000 0 CP110_PCIEx_MEM_BASE(1) 0  CP110_PCIEx_MEM_BASE(1) 0 0xf00000>;
-               interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &CP110_LABEL(icu_nsr) 24 IRQ_TYPE_LEVEL_HIGH>;
-               interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
-
-               num-lanes = <1>;
-               clock-names = "core", "reg";
-               clocks = <&CP110_LABEL(clk) 1 11>, <&CP110_LABEL(clk) 1 14>;
-               status = "disabled";
-       };
-
-       CP110_LABEL(pcie2): pcie@CP110_PCIE2_BASE {
-               compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
-               reg = <0 ADDRESSIFY(CP110_PCIE2_BASE) 0 0x10000>,
-                     <0 CP110_PCIEx_CONF_BASE(2) 0 0x80000>;
-               reg-names = "ctrl", "config";
-               #address-cells = <3>;
-               #size-cells = <2>;
-               #interrupt-cells = <1>;
-               device_type = "pci";
-               dma-coherent;
-               msi-parent = <&gic_v2m0>;
-
-               bus-range = <0 0xff>;
-               ranges =
-               /* downstream I/O */
-               <0x81000000 0 CP110_PCIEx_IO_BASE(2) 0  CP110_PCIEx_IO_BASE(2) 0 0x10000
-               /* non-prefetchable memory */
-               0x82000000 0 CP110_PCIEx_MEM_BASE(2) 0  CP110_PCIEx_MEM_BASE(2) 0 0xf00000>;
-               interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &CP110_LABEL(icu_nsr) 23 IRQ_TYPE_LEVEL_HIGH>;
-               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
-
-               num-lanes = <1>;
-               clock-names = "core", "reg";
-               clocks = <&CP110_LABEL(clk) 1 12>, <&CP110_LABEL(clk) 1 14>;
-               status = "disabled";
-       };
-};
+#undef CP11X_TYPE
diff --git a/arch/arm64/boot/dts/marvell/armada-cp115.dtsi b/arch/arm64/boot/dts/marvell/armada-cp115.dtsi
new file mode 100644 (file)
index 0000000..1d0a965
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Marvell Technology Group Ltd.
+ *
+ * Device Tree file for Marvell Armada CP115.
+ */
+
+#define CP11X_TYPE cp115
+
+#include "armada-cp11x.dtsi"
+
+#undef CP11X_TYPE
diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
new file mode 100644 (file)
index 0000000..9dcf16b
--- /dev/null
@@ -0,0 +1,568 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2016 Marvell Technology Group Ltd.
+ *
+ * Device Tree file for Marvell Armada CP11x.
+ */
+
+#include <dt-bindings/interrupt-controller/mvebu-icu.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "armada-common.dtsi"
+
+#define CP11X_PCIEx_CONF_BASE(iface)   (CP11X_PCIEx_MEM_BASE(iface) + CP11X_PCIEx_MEM_SIZE(iface))
+
+/ {
+       /*
+        * The contents of the node are defined below, in order to
+        * save one indentation level
+        */
+       CP11X_NAME: CP11X_NAME { };
+
+       /*
+        * CPs only have one sensor in the thermal IC.
+        *
+        * The cooling maps are empty as there are no cooling devices.
+        */
+       thermal-zones {
+               CP11X_LABEL(thermal_ic): CP11X_NODE_NAME(thermal-ic) {
+                       polling-delay-passive = <0>; /* Interrupt driven */
+                       polling-delay = <0>; /* Interrupt driven */
+
+                       thermal-sensors = <&CP11X_LABEL(thermal) 0>;
+
+                       trips {
+                               CP11X_LABEL(crit): crit {
+                                       temperature = <100000>; /* mC degrees */
+                                       hysteresis = <2000>; /* mC degrees */
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps { };
+               };
+       };
+};
+
+&CP11X_NAME {
+       #address-cells = <2>;
+       #size-cells = <2>;
+       compatible = "simple-bus";
+       interrupt-parent = <&CP11X_LABEL(icu_nsr)>;
+       ranges;
+
+       config-space@CP11X_BASE {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges = <0x0 0x0 ADDRESSIFY(CP11X_BASE) 0x2000000>;
+
+               CP11X_LABEL(ethernet): ethernet@0 {
+                       compatible = "marvell,armada-7k-pp22";
+                       reg = <0x0 0x100000>, <0x129000 0xb000>;
+                       clocks = <&CP11X_LABEL(clk) 1 3>, <&CP11X_LABEL(clk) 1 9>,
+                                <&CP11X_LABEL(clk) 1 5>, <&CP11X_LABEL(clk) 1 6>,
+                                <&CP11X_LABEL(clk) 1 18>;
+                       clock-names = "pp_clk", "gop_clk",
+                                     "mg_clk", "mg_core_clk", "axi_clk";
+                       marvell,system-controller = <&CP11X_LABEL(syscon0)>;
+                       status = "disabled";
+                       dma-coherent;
+
+                       CP11X_LABEL(eth0): eth0 {
+                               interrupts = <39 IRQ_TYPE_LEVEL_HIGH>,
+                                       <43 IRQ_TYPE_LEVEL_HIGH>,
+                                       <47 IRQ_TYPE_LEVEL_HIGH>,
+                                       <51 IRQ_TYPE_LEVEL_HIGH>,
+                                       <55 IRQ_TYPE_LEVEL_HIGH>,
+                                       <59 IRQ_TYPE_LEVEL_HIGH>,
+                                       <63 IRQ_TYPE_LEVEL_HIGH>,
+                                       <67 IRQ_TYPE_LEVEL_HIGH>,
+                                       <71 IRQ_TYPE_LEVEL_HIGH>,
+                                       <129 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "hif0", "hif1", "hif2",
+                                       "hif3", "hif4", "hif5", "hif6", "hif7",
+                                       "hif8", "link";
+                               port-id = <0>;
+                               gop-port-id = <0>;
+                               status = "disabled";
+                       };
+
+                       CP11X_LABEL(eth1): eth1 {
+                               interrupts = <40 IRQ_TYPE_LEVEL_HIGH>,
+                                       <44 IRQ_TYPE_LEVEL_HIGH>,
+                                       <48 IRQ_TYPE_LEVEL_HIGH>,
+                                       <52 IRQ_TYPE_LEVEL_HIGH>,
+                                       <56 IRQ_TYPE_LEVEL_HIGH>,
+                                       <60 IRQ_TYPE_LEVEL_HIGH>,
+                                       <64 IRQ_TYPE_LEVEL_HIGH>,
+                                       <68 IRQ_TYPE_LEVEL_HIGH>,
+                                       <72 IRQ_TYPE_LEVEL_HIGH>,
+                                       <128 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "hif0", "hif1", "hif2",
+                                       "hif3", "hif4", "hif5", "hif6", "hif7",
+                                       "hif8", "link";
+                               port-id = <1>;
+                               gop-port-id = <2>;
+                               status = "disabled";
+                       };
+
+                       CP11X_LABEL(eth2): eth2 {
+                               interrupts = <41 IRQ_TYPE_LEVEL_HIGH>,
+                                       <45 IRQ_TYPE_LEVEL_HIGH>,
+                                       <49 IRQ_TYPE_LEVEL_HIGH>,
+                                       <53 IRQ_TYPE_LEVEL_HIGH>,
+                                       <57 IRQ_TYPE_LEVEL_HIGH>,
+                                       <61 IRQ_TYPE_LEVEL_HIGH>,
+                                       <65 IRQ_TYPE_LEVEL_HIGH>,
+                                       <69 IRQ_TYPE_LEVEL_HIGH>,
+                                       <73 IRQ_TYPE_LEVEL_HIGH>,
+                                       <127 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "hif0", "hif1", "hif2",
+                                       "hif3", "hif4", "hif5", "hif6", "hif7",
+                                       "hif8", "link";
+                               port-id = <2>;
+                               gop-port-id = <3>;
+                               status = "disabled";
+                       };
+               };
+
+               CP11X_LABEL(comphy): phy@120000 {
+                       compatible = "marvell,comphy-cp110";
+                       reg = <0x120000 0x6000>;
+                       marvell,system-controller = <&CP11X_LABEL(syscon0)>;
+                       clocks = <&CP11X_LABEL(clk) 1 5>, <&CP11X_LABEL(clk) 1 6>,
+                                <&CP11X_LABEL(clk) 1 18>;
+                       clock-names = "mg_clk", "mg_core_clk", "axi_clk";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       CP11X_LABEL(comphy0): phy@0 {
+                               reg = <0>;
+                               #phy-cells = <1>;
+                       };
+
+                       CP11X_LABEL(comphy1): phy@1 {
+                               reg = <1>;
+                               #phy-cells = <1>;
+                       };
+
+                       CP11X_LABEL(comphy2): phy@2 {
+                               reg = <2>;
+                               #phy-cells = <1>;
+                       };
+
+                       CP11X_LABEL(comphy3): phy@3 {
+                               reg = <3>;
+                               #phy-cells = <1>;
+                       };
+
+                       CP11X_LABEL(comphy4): phy@4 {
+                               reg = <4>;
+                               #phy-cells = <1>;
+                       };
+
+                       CP11X_LABEL(comphy5): phy@5 {
+                               reg = <5>;
+                               #phy-cells = <1>;
+                       };
+               };
+
+               CP11X_LABEL(mdio): mdio@12a200 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "marvell,orion-mdio";
+                       reg = <0x12a200 0x10>;
+                       clocks = <&CP11X_LABEL(clk) 1 9>, <&CP11X_LABEL(clk) 1 5>,
+                                <&CP11X_LABEL(clk) 1 6>, <&CP11X_LABEL(clk) 1 18>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(xmdio): mdio@12a600 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "marvell,xmdio";
+                       reg = <0x12a600 0x10>;
+                       clocks = <&CP11X_LABEL(clk) 1 5>,
+                                <&CP11X_LABEL(clk) 1 6>, <&CP11X_LABEL(clk) 1 18>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(icu): interrupt-controller@1e0000 {
+                       compatible = "marvell,cp110-icu";
+                       reg = <0x1e0000 0x440>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       CP11X_LABEL(icu_nsr): interrupt-controller@10 {
+                               compatible = "marvell,cp110-icu-nsr";
+                               reg = <0x10 0x20>;
+                               #interrupt-cells = <2>;
+                               interrupt-controller;
+                               msi-parent = <&gicp>;
+                       };
+
+                       CP11X_LABEL(icu_sei): interrupt-controller@50 {
+                               compatible = "marvell,cp110-icu-sei";
+                               reg = <0x50 0x10>;
+                               #interrupt-cells = <2>;
+                               interrupt-controller;
+                               msi-parent = <&sei>;
+                       };
+               };
+
+               CP11X_LABEL(rtc): rtc@284000 {
+                       compatible = "marvell,armada-8k-rtc";
+                       reg = <0x284000 0x20>, <0x284080 0x24>;
+                       reg-names = "rtc", "rtc-soc";
+                       interrupts = <77 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               CP11X_LABEL(syscon0): system-controller@440000 {
+                       compatible = "syscon", "simple-mfd";
+                       reg = <0x440000 0x2000>;
+
+                       CP11X_LABEL(clk): clock {
+                               compatible = "marvell,cp110-clock";
+                               #clock-cells = <2>;
+                       };
+
+                       CP11X_LABEL(gpio1): gpio@100 {
+                               compatible = "marvell,armada-8k-gpio";
+                               offset = <0x100>;
+                               ngpios = <32>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               gpio-ranges = <&CP11X_LABEL(pinctrl) 0 0 32>;
+                               interrupt-controller;
+                               interrupts = <86 IRQ_TYPE_LEVEL_HIGH>,
+                                       <85 IRQ_TYPE_LEVEL_HIGH>,
+                                       <84 IRQ_TYPE_LEVEL_HIGH>,
+                                       <83 IRQ_TYPE_LEVEL_HIGH>;
+                               #interrupt-cells = <2>;
+                               status = "disabled";
+                       };
+
+                       CP11X_LABEL(gpio2): gpio@140 {
+                               compatible = "marvell,armada-8k-gpio";
+                               offset = <0x140>;
+                               ngpios = <31>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               gpio-ranges = <&CP11X_LABEL(pinctrl) 0 32 31>;
+                               interrupt-controller;
+                               interrupts = <82 IRQ_TYPE_LEVEL_HIGH>,
+                                       <81 IRQ_TYPE_LEVEL_HIGH>,
+                                       <80 IRQ_TYPE_LEVEL_HIGH>,
+                                       <79 IRQ_TYPE_LEVEL_HIGH>;
+                               #interrupt-cells = <2>;
+                               status = "disabled";
+                       };
+               };
+
+               CP11X_LABEL(syscon1): system-controller@400000 {
+                       compatible = "syscon", "simple-mfd";
+                       reg = <0x400000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       CP11X_LABEL(thermal): thermal-sensor@70 {
+                               compatible = "marvell,armada-cp110-thermal";
+                               reg = <0x70 0x10>;
+                               interrupts-extended =
+                                       <&CP11X_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>;
+                               #thermal-sensor-cells = <1>;
+                       };
+               };
+
+               CP11X_LABEL(usb3_0): usb3@500000 {
+                       compatible = "marvell,armada-8k-xhci",
+                       "generic-xhci";
+                       reg = <0x500000 0x4000>;
+                       dma-coherent;
+                       interrupts = <106 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 22>,
+                                <&CP11X_LABEL(clk) 1 16>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(usb3_1): usb3@510000 {
+                       compatible = "marvell,armada-8k-xhci",
+                       "generic-xhci";
+                       reg = <0x510000 0x4000>;
+                       dma-coherent;
+                       interrupts = <105 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 23>,
+                                <&CP11X_LABEL(clk) 1 16>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(sata0): sata@540000 {
+                       compatible = "marvell,armada-8k-ahci",
+                       "generic-ahci";
+                       reg = <0x540000 0x30000>;
+                       dma-coherent;
+                       interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&CP11X_LABEL(clk) 1 15>,
+                                <&CP11X_LABEL(clk) 1 16>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+                       sata-port@0 {
+                               reg = <0>;
+                       };
+
+                       sata-port@1 {
+                               reg = <1>;
+                       };
+               };
+
+               CP11X_LABEL(xor0): xor@6a0000 {
+                       compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+                       reg = <0x6a0000 0x1000>, <0x6b0000 0x1000>;
+                       dma-coherent;
+                       msi-parent = <&gic_v2m0>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 8>,
+                                <&CP11X_LABEL(clk) 1 14>;
+               };
+
+               CP11X_LABEL(xor1): xor@6c0000 {
+                       compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+                       reg = <0x6c0000 0x1000>, <0x6d0000 0x1000>;
+                       dma-coherent;
+                       msi-parent = <&gic_v2m0>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 7>,
+                                <&CP11X_LABEL(clk) 1 14>;
+               };
+
+               CP11X_LABEL(spi0): spi@700600 {
+                       compatible = "marvell,armada-380-spi";
+                       reg = <0x700600 0x50>;
+                       #address-cells = <0x1>;
+                       #size-cells = <0x0>;
+                       clock-names = "core", "axi";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(spi1): spi@700680 {
+                       compatible = "marvell,armada-380-spi";
+                       reg = <0x700680 0x50>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clock-names = "core", "axi";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(i2c0): i2c@701000 {
+                       compatible = "marvell,mv78230-i2c";
+                       reg = <0x701000 0x20>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(i2c1): i2c@701100 {
+                       compatible = "marvell,mv78230-i2c";
+                       reg = <0x701100 0x20>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(uart0): serial@702000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x702000 0x100>;
+                       reg-shift = <2>;
+                       interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-io-width = <1>;
+                       clock-names = "baudclk", "apb_pclk";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(uart1): serial@702100 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x702100 0x100>;
+                       reg-shift = <2>;
+                       interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-io-width = <1>;
+                       clock-names = "baudclk", "apb_pclk";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(uart2): serial@702200 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x702200 0x100>;
+                       reg-shift = <2>;
+                       interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-io-width = <1>;
+                       clock-names = "baudclk", "apb_pclk";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(uart3): serial@702300 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x702300 0x100>;
+                       reg-shift = <2>;
+                       interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-io-width = <1>;
+                       clock-names = "baudclk", "apb_pclk";
+                       clocks = <&CP11X_LABEL(clk) 1 21>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(nand_controller): nand@720000 {
+                       /*
+                        * Due to the limitation of the pins available
+                        * this controller is only usable on the CPM
+                        * for A7K and on the CPS for A8K.
+                        */
+                       compatible = "marvell,armada-8k-nand-controller",
+                               "marvell,armada370-nand-controller";
+                       reg = <0x720000 0x54>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <115 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 2>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       marvell,system-controller = <&CP11X_LABEL(syscon0)>;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(trng): trng@760000 {
+                       compatible = "marvell,armada-8k-rng",
+                       "inside-secure,safexcel-eip76";
+                       reg = <0x760000 0x7d>;
+                       interrupts = <95 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 25>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       status = "okay";
+               };
+
+               CP11X_LABEL(sdhci0): sdhci@780000 {
+                       compatible = "marvell,armada-cp110-sdhci";
+                       reg = <0x780000 0x300>;
+                       interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "core", "axi";
+                       clocks = <&CP11X_LABEL(clk) 1 4>, <&CP11X_LABEL(clk) 1 18>;
+                       dma-coherent;
+                       status = "disabled";
+               };
+
+               CP11X_LABEL(crypto): crypto@800000 {
+                       compatible = "inside-secure,safexcel-eip197b";
+                       reg = <0x800000 0x200000>;
+                       interrupts = <87 IRQ_TYPE_LEVEL_HIGH>,
+                               <88 IRQ_TYPE_LEVEL_HIGH>,
+                               <89 IRQ_TYPE_LEVEL_HIGH>,
+                               <90 IRQ_TYPE_LEVEL_HIGH>,
+                               <91 IRQ_TYPE_LEVEL_HIGH>,
+                               <92 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "mem", "ring0", "ring1",
+                               "ring2", "ring3", "eip";
+                       clock-names = "core", "reg";
+                       clocks = <&CP11X_LABEL(clk) 1 26>,
+                                <&CP11X_LABEL(clk) 1 17>;
+                       dma-coherent;
+               };
+       };
+
+       CP11X_LABEL(pcie0): pcie@CP11X_PCIE0_BASE {
+               compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+               reg = <0 ADDRESSIFY(CP11X_PCIE0_BASE) 0 0x10000>,
+                     <0 CP11X_PCIEx_CONF_BASE(0) 0 0x80000>;
+               reg-names = "ctrl", "config";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+               device_type = "pci";
+               dma-coherent;
+               msi-parent = <&gic_v2m0>;
+
+               bus-range = <0 0xff>;
+               /* non-prefetchable memory */
+               ranges = <0x82000000 0 CP11X_PCIEx_MEM_BASE(0) 0  CP11X_PCIEx_MEM_BASE(0) 0 CP11X_PCIEx_MEM_SIZE(0)>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &CP11X_LABEL(icu_nsr) 22 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
+               num-lanes = <1>;
+               clock-names = "core", "reg";
+               clocks = <&CP11X_LABEL(clk) 1 13>, <&CP11X_LABEL(clk) 1 14>;
+               status = "disabled";
+       };
+
+       CP11X_LABEL(pcie1): pcie@CP11X_PCIE1_BASE {
+               compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+               reg = <0 ADDRESSIFY(CP11X_PCIE1_BASE) 0 0x10000>,
+                     <0 CP11X_PCIEx_CONF_BASE(1) 0 0x80000>;
+               reg-names = "ctrl", "config";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+               device_type = "pci";
+               dma-coherent;
+               msi-parent = <&gic_v2m0>;
+
+               bus-range = <0 0xff>;
+               /* non-prefetchable memory */
+               ranges = <0x82000000 0 CP11X_PCIEx_MEM_BASE(1) 0  CP11X_PCIEx_MEM_BASE(1) 0 CP11X_PCIEx_MEM_SIZE(1)>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &CP11X_LABEL(icu_nsr) 24 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
+
+               num-lanes = <1>;
+               clock-names = "core", "reg";
+               clocks = <&CP11X_LABEL(clk) 1 11>, <&CP11X_LABEL(clk) 1 14>;
+               status = "disabled";
+       };
+
+       CP11X_LABEL(pcie2): pcie@CP11X_PCIE2_BASE {
+               compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+               reg = <0 ADDRESSIFY(CP11X_PCIE2_BASE) 0 0x10000>,
+                     <0 CP11X_PCIEx_CONF_BASE(2) 0 0x80000>;
+               reg-names = "ctrl", "config";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+               device_type = "pci";
+               dma-coherent;
+               msi-parent = <&gic_v2m0>;
+
+               bus-range = <0 0xff>;
+               /* non-prefetchable memory */
+               ranges = <0x82000000 0 CP11X_PCIEx_MEM_BASE(2) 0  CP11X_PCIEx_MEM_BASE(2) 0 CP11X_PCIEx_MEM_SIZE(2)>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &CP11X_LABEL(icu_nsr) 23 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
+
+               num-lanes = <1>;
+               clock-names = "core", "reg";
+               clocks = <&CP11X_LABEL(clk) 1 12>, <&CP11X_LABEL(clk) 1 14>;
+               status = "disabled";
+       };
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dts b/arch/arm64/boot/dts/marvell/cn9130-db.dts
new file mode 100644 (file)
index 0000000..ce49a70
--- /dev/null
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Marvell International Ltd.
+ *
+ * Device tree for the CN9130-DB board.
+ */
+
+#include "cn9130.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Marvell Armada CN9130-DB";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       aliases {
+               gpio1 = &cp0_gpio1;
+               gpio2 = &cp0_gpio2;
+               i2c0 = &cp0_i2c0;
+               ethernet0 = &cp0_eth0;
+               ethernet1 = &cp0_eth1;
+               ethernet2 = &cp0_eth2;
+               spi1 = &cp0_spi0;
+               spi2 = &cp0_spi1;
+       };
+
+       memory@00000000 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x80000000>;
+       };
+
+       ap0_reg_sd_vccq: ap0_sd_vccq@0 {
+               compatible = "regulator-gpio";
+               regulator-name = "ap0_sd_vccq";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               gpios = <&expander0 8 GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x1 3300000 0x0>;
+       };
+
+       cp0_reg_usb3_vbus0: cp0_usb3_vbus@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "cp0-xhci0-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&expander0 0 GPIO_ACTIVE_HIGH>;
+       };
+
+       cp0_usb3_0_phy0: cp0_usb3_phy@0 {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&cp0_reg_usb3_vbus0>;
+       };
+
+       cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "cp0-xhci1-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&expander0 1 GPIO_ACTIVE_HIGH>;
+       };
+
+       cp0_usb3_0_phy1: cp0_usb3_phy@1 {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&cp0_reg_usb3_vbus1>;
+       };
+
+       cp0_reg_sd_vccq: cp0_sd_vccq@0 {
+               compatible = "regulator-gpio";
+               regulator-name = "cp0_sd_vccq";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               gpios = <&expander0 15 GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x1
+                         3300000 0x0>;
+       };
+
+       cp0_reg_sd_vcc: cp0_sd_vcc@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "cp0_sd_vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&expander0 14 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
+       cp0_sfp_eth0: sfp-eth@0 {
+               compatible = "sff,sfp";
+               i2c-bus = <&cp0_sfpp0_i2c>;
+               los-gpio = <&cp0_module_expander1 11 GPIO_ACTIVE_HIGH>;
+               mod-def0-gpio = <&cp0_module_expander1 10 GPIO_ACTIVE_LOW>;
+               tx-disable-gpio = <&cp0_module_expander1 9 GPIO_ACTIVE_HIGH>;
+               tx-fault-gpio = <&cp0_module_expander1 8 GPIO_ACTIVE_HIGH>;
+               /*
+                * SFP cages are unconnected on early PCBs because of an the I2C
+                * lanes not being connected. Prevent the port for being
+                * unusable by disabling the SFP node.
+                */
+               status = "disabled";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+/* on-board eMMC - U9 */
+&ap_sdhci0 {
+       pinctrl-names = "default";
+       bus-width = <8>;
+       vqmmc-supply = <&ap0_reg_sd_vccq>;
+       status = "okay";
+};
+
+&cp0_crypto {
+       status = "disabled";
+};
+
+&cp0_ethernet {
+       status = "okay";
+};
+
+/* SLM-1521-V2, CON9 */
+&cp0_eth0 {
+       status = "disabled";
+       phy-mode = "10gbase-kr";
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp0_comphy4 0>;
+       managed = "in-band-status";
+       sfp = <&cp0_sfp_eth0>;
+};
+
+/* CON56 */
+&cp0_eth1 {
+       status = "okay";
+       phy = <&phy0>;
+       phy-mode = "rgmii-id";
+};
+
+/* CON57 */
+&cp0_eth2 {
+       status = "okay";
+       phy = <&phy1>;
+       phy-mode = "rgmii-id";
+};
+
+&cp0_gpio1 {
+       status = "okay";
+};
+
+&cp0_gpio2 {
+       status = "okay";
+};
+
+&cp0_i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp0_i2c0_pins>;
+       clock-frequency = <100000>;
+
+       /* U36 */
+       expander0: pca953x@21 {
+               compatible = "nxp,pca9555";
+               pinctrl-names = "default";
+               gpio-controller;
+               #gpio-cells = <2>;
+               reg = <0x21>;
+               status = "okay";
+       };
+
+       /* U42 */
+       eeprom0: eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+               pagesize = <0x20>;
+       };
+
+       /* U38 */
+       eeprom1: eeprom@57 {
+               compatible = "atmel,24c64";
+               reg = <0x57>;
+               pagesize = <0x20>;
+       };
+};
+
+&cp0_i2c1 {
+       status = "okay";
+       clock-frequency = <100000>;
+
+       /* SLM-1521-V2 - U3 */
+       i2c-mux@72 { /* verify address - depends on dpr */
+               compatible = "nxp,pca9544";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x72>;
+               cp0_sfpp0_i2c: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+                       /* U12 */
+                       cp0_module_expander1: pca9555@21 {
+                               compatible = "nxp,pca9555";
+                               pinctrl-names = "default";
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               reg = <0x21>;
+                       };
+
+               };
+       };
+};
+
+&cp0_mdio {
+       status = "okay";
+
+       phy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
+/* U54 */
+&cp0_nand_controller {
+       pinctrl-names = "default";
+       pinctrl-0 = <&nand_pins &nand_rb>;
+
+       nand@0 {
+               reg = <0>;
+               label = "main-storage";
+               nand-rb = <0>;
+               nand-ecc-mode = "hw";
+               nand-on-flash-bbt;
+               nand-ecc-strength = <8>;
+               nand-ecc-step-size = <512>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "U-Boot";
+                               reg = <0 0x200000>;
+                       };
+                       partition@200000 {
+                               label = "Linux";
+                               reg = <0x200000 0xd00000>;
+                       };
+                       partition@1000000 {
+                               label = "Filesystem";
+                               reg = <0x1000000 0x3f000000>;
+                       };
+               };
+       };
+};
+
+/* SLM-1521-V2, CON6 */
+&cp0_pcie0 {
+       status = "okay";
+       num-lanes = <4>;
+       num-viewport = <8>;
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp0_comphy0 0
+               &cp0_comphy1 0
+               &cp0_comphy2 0
+               &cp0_comphy3 0>;
+};
+
+&cp0_sata0 {
+       status = "okay";
+
+       /* SLM-1521-V2, CON2 */
+       sata-port@1 {
+               status = "okay";
+               /* Generic PHY, providing serdes lanes */
+               phys = <&cp0_comphy5 1>;
+       };
+};
+
+/* CON 28 */
+&cp0_sdhci0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp0_sdhci_pins
+                    &cp0_sdhci_cd_pins>;
+       bus-width = <4>;
+       cd-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>;
+       no-1-8-v;
+       vqmmc-supply = <&cp0_reg_sd_vccq>;
+       vmmc-supply = <&cp0_reg_sd_vcc>;
+};
+
+/* U55 */
+&cp0_spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp0_spi0_pins>;
+       reg = <0x700680 0x50>;
+
+       spi-flash@0 {
+               #address-cells = <0x1>;
+               #size-cells = <0x1>;
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               /* On-board MUX does not allow higher frequencies */
+               spi-max-frequency = <40000000>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "U-Boot-0";
+                               reg = <0x0 0x200000>;
+                       };
+
+                       partition@400000 {
+                               label = "Filesystem-0";
+                               reg = <0x200000 0xe00000>;
+                       };
+               };
+       };
+};
+
+&cp0_syscon0 {
+       cp0_pinctrl: pinctrl {
+               compatible = "marvell,cp115-standalone-pinctrl";
+
+               cp0_i2c0_pins: cp0-i2c-pins-0 {
+                       marvell,pins = "mpp37", "mpp38";
+                       marvell,function = "i2c0";
+               };
+               cp0_i2c1_pins: cp0-i2c-pins-1 {
+                       marvell,pins = "mpp35", "mpp36";
+                       marvell,function = "i2c1";
+               };
+               cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 {
+                       marvell,pins = "mpp0", "mpp1", "mpp2",
+                                      "mpp3", "mpp4", "mpp5",
+                                      "mpp6", "mpp7", "mpp8",
+                                      "mpp9", "mpp10", "mpp11";
+                       marvell,function = "ge0";
+               };
+               cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 {
+                       marvell,pins = "mpp44", "mpp45", "mpp46",
+                                      "mpp47", "mpp48", "mpp49",
+                                      "mpp50", "mpp51", "mpp52",
+                                      "mpp53", "mpp54", "mpp55";
+                       marvell,function = "ge1";
+               };
+               cp0_sdhci_cd_pins: cp0-sdhci-cd-pins-0 {
+                       marvell,pins = "mpp43";
+                       marvell,function = "gpio";
+               };
+               cp0_sdhci_pins: cp0-sdhi-pins-0 {
+                       marvell,pins = "mpp56", "mpp57", "mpp58",
+                                      "mpp59", "mpp60", "mpp61";
+                       marvell,function = "sdio";
+               };
+               cp0_spi0_pins: cp0-spi-pins-0 {
+                       marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+                       marvell,function = "spi1";
+               };
+               nand_pins: nand-pins {
+                       marvell,pins = "mpp15", "mpp16", "mpp17", "mpp18",
+                                      "mpp19", "mpp20", "mpp21", "mpp22",
+                                      "mpp23", "mpp24", "mpp25", "mpp26",
+                                      "mpp27";
+                       marvell,function = "dev";
+               };
+               nand_rb: nand-rb {
+                       marvell,pins = "mpp13";
+                       marvell,function = "nf";
+               };
+       };
+};
+
+&cp0_usb3_0 {
+       status = "okay";
+       usb-phy = <&cp0_usb3_0_phy0>;
+       phy-names = "usb";
+};
+
+&cp0_usb3_1 {
+       status = "okay";
+       usb-phy = <&cp0_usb3_0_phy1>;
+       phy-names = "usb";
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9130.dtsi b/arch/arm64/boot/dts/marvell/cn9130.dtsi
new file mode 100644 (file)
index 0000000..a2b7e5e
--- /dev/null
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Marvell International Ltd.
+ *
+ * Device tree for the CN9130 SoC.
+ */
+
+#include "armada-ap807-quad.dtsi"
+
+/ {
+       model = "Marvell Armada CN9130 SoC";
+       compatible = "marvell,cn9130", "marvell,armada-ap807-quad",
+                    "marvell,armada-ap807";
+};
+
+/*
+ * Instantiate the internal CP115
+ */
+
+#define CP11X_NAME             cp0
+#define CP11X_BASE             f2000000
+#define CP11X_PCIEx_MEM_BASE(iface) ((iface == 0) ? 0xc0000000 : \
+                                                   0xe0000000 + ((iface - 1) * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) ((iface == 0) ? 0x1ff00000 : 0xf00000)
+#define CP11X_PCIE0_BASE       f2600000
+#define CP11X_PCIE1_BASE       f2620000
+#define CP11X_PCIE2_BASE       f2640000
+
+#include "armada-cp115.dtsi"
+
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
diff --git a/arch/arm64/boot/dts/marvell/cn9131-db.dts b/arch/arm64/boot/dts/marvell/cn9131-db.dts
new file mode 100644 (file)
index 0000000..3c975f9
--- /dev/null
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Marvell International Ltd.
+ *
+ * Device tree for the CN9131-DB board.
+ */
+
+#include "cn9130-db.dts"
+
+/ {
+       model = "Marvell Armada CN9131-DB";
+       compatible = "marvell,cn9131", "marvell,cn9130",
+                    "marvell,armada-ap807-quad", "marvell,armada-ap807";
+
+       aliases {
+               gpio3 = &cp1_gpio1;
+               gpio4 = &cp1_gpio2;
+               ethernet3 = &cp1_eth0;
+               ethernet4 = &cp1_eth1;
+       };
+
+       cp1_reg_usb3_vbus0: cp1_usb3_vbus@0 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&cp1_xhci0_vbus_pins>;
+               regulator-name = "cp1-xhci0-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&cp1_gpio1 3 GPIO_ACTIVE_HIGH>;
+       };
+
+       cp1_usb3_0_phy0: cp1_usb3_phy0 {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&cp1_reg_usb3_vbus0>;
+       };
+
+       cp1_sfp_eth1: sfp-eth1 {
+               compatible = "sff,sfp";
+               i2c-bus = <&cp1_i2c0>;
+               los-gpio = <&cp1_gpio1 11 GPIO_ACTIVE_HIGH>;
+               mod-def0-gpio = <&cp1_gpio1 10 GPIO_ACTIVE_LOW>;
+               tx-disable-gpio = <&cp1_gpio1 9 GPIO_ACTIVE_HIGH>;
+               tx-fault-gpio = <&cp1_gpio1 8 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&cp1_sfp_pins>;
+               /*
+                * SFP cages are unconnected on early PCBs because of an the I2C
+                * lanes not being connected. Prevent the port for being
+                * unusable by disabling the SFP node.
+                */
+               status = "disabled";
+       };
+};
+
+/*
+ * Instantiate the first slave CP115
+ */
+
+#define CP11X_NAME             cp1
+#define CP11X_BASE             f4000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xe2000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE       f4600000
+#define CP11X_PCIE1_BASE       f4620000
+#define CP11X_PCIE2_BASE       f4640000
+
+#include "armada-cp115.dtsi"
+
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
+
+&cp1_crypto {
+       status = "disabled";
+};
+
+&cp1_ethernet {
+       status = "okay";
+};
+
+/* CON50 */
+&cp1_eth0 {
+       status = "disabled";
+       phy-mode = "10gbase-kr";
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp1_comphy4 0>;
+       managed = "in-band-status";
+       sfp = <&cp1_sfp_eth1>;
+};
+
+&cp1_gpio1 {
+       status = "okay";
+};
+
+&cp1_gpio2 {
+       status = "okay";
+};
+
+&cp1_i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp1_i2c0_pins>;
+       clock-frequency = <100000>;
+};
+
+/* CON40 */
+&cp1_pcie0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp1_pcie_reset_pins>;
+       num-lanes = <2>;
+       num-viewport = <8>;
+       marvell,reset-gpio = <&cp1_gpio1 0 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp1_comphy0 0
+               &cp1_comphy1 0>;
+};
+
+&cp1_sata0 {
+       status = "okay";
+
+       /* CON32 */
+       sata-port@1 {
+               /* Generic PHY, providing serdes lanes */
+               phys = <&cp1_comphy5 1>;
+       };
+};
+
+/* U24 */
+&cp1_spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp1_spi0_pins>;
+       reg = <0x700680 0x50>;
+
+       spi-flash@0 {
+               #address-cells = <0x1>;
+               #size-cells = <0x1>;
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               /* On-board MUX does not allow higher frequencies */
+               spi-max-frequency = <40000000>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "U-Boot-1";
+                               reg = <0x0 0x200000>;
+                       };
+
+                       partition@400000 {
+                               label = "Filesystem-1";
+                               reg = <0x200000 0xe00000>;
+                       };
+               };
+       };
+
+};
+
+&cp1_syscon0 {
+       cp1_pinctrl: pinctrl {
+               compatible = "marvell,cp115-standalone-pinctrl";
+
+               cp1_i2c0_pins: cp1-i2c-pins-0 {
+                       marvell,pins = "mpp37", "mpp38";
+                       marvell,function = "i2c0";
+               };
+               cp1_spi0_pins: cp1-spi-pins-0 {
+                       marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+                       marvell,function = "spi1";
+               };
+               cp1_xhci0_vbus_pins: cp1-xhci0-vbus-pins {
+                       marvell,pins = "mpp3";
+                       marvell,function = "gpio";
+               };
+               cp1_sfp_pins: sfp-pins {
+                       marvell,pins = "mpp8", "mpp9", "mpp10", "mpp11";
+                       marvell,function = "gpio";
+               };
+               cp1_pcie_reset_pins: cp1-pcie-reset-pins {
+                       marvell,pins = "mpp0";
+                       marvell,function = "gpio";
+               };
+       };
+};
+
+/* CON58 */
+&cp1_usb3_1 {
+       status = "okay";
+       usb-phy = <&cp1_usb3_0_phy0>;
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp1_comphy3 1>;
+       phy-names = "usb";
+};
diff --git a/arch/arm64/boot/dts/marvell/cn9132-db.dts b/arch/arm64/boot/dts/marvell/cn9132-db.dts
new file mode 100644 (file)
index 0000000..4ef0df3
--- /dev/null
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Marvell International Ltd.
+ *
+ * Device tree for the CN9132-DB board.
+ */
+
+#include "cn9131-db.dts"
+
+/ {
+       model = "Marvell Armada CN9132-DB";
+       compatible = "marvell,cn9132", "marvell,cn9131", "marvell,cn9130",
+                    "marvell,armada-ap807-quad", "marvell,armada-ap807";
+
+       aliases {
+               gpio5 = &cp2_gpio1;
+               gpio6 = &cp2_gpio2;
+               ethernet5 = &cp2_eth0;
+       };
+
+       cp2_reg_usb3_vbus0: cp2_usb3_vbus@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "cp2-xhci0-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&cp2_gpio1 2 GPIO_ACTIVE_HIGH>;
+       };
+
+       cp2_usb3_0_phy0: cp2_usb3_phy0 {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&cp2_reg_usb3_vbus0>;
+       };
+
+       cp2_reg_usb3_vbus1: cp2_usb3_vbus@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "cp2-xhci1-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&cp2_gpio1 3 GPIO_ACTIVE_HIGH>;
+       };
+
+       cp2_usb3_0_phy1: cp2_usb3_phy1 {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&cp2_reg_usb3_vbus1>;
+       };
+
+       cp2_reg_sd_vccq: cp2_sd_vccq@0 {
+               compatible = "regulator-gpio";
+               regulator-name = "cp2_sd_vcc";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               gpios = <&cp2_gpio2 17 GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x1 3300000 0x0>;
+       };
+
+       cp2_sfp_eth0: sfp-eth0 {
+               compatible = "sff,sfp";
+               i2c-bus = <&cp2_sfpp0_i2c>;
+               los-gpio = <&cp2_module_expander1 11 GPIO_ACTIVE_HIGH>;
+               mod-def0-gpio = <&cp2_module_expander1 10 GPIO_ACTIVE_LOW>;
+               tx-disable-gpio = <&cp2_module_expander1 9 GPIO_ACTIVE_HIGH>;
+               tx-fault-gpio = <&cp2_module_expander1 8 GPIO_ACTIVE_HIGH>;
+               /*
+                * SFP cages are unconnected on early PCBs because of an the I2C
+                * lanes not being connected. Prevent the port for being
+                * unusable by disabling the SFP node.
+                */
+               status = "disabled";
+       };
+};
+
+/*
+ * Instantiate the second slave CP115
+ */
+
+#define CP11X_NAME             cp2
+#define CP11X_BASE             f6000000
+#define CP11X_PCIEx_MEM_BASE(iface) (0xe5000000 + (iface * 0x1000000))
+#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
+#define CP11X_PCIE0_BASE       f6600000
+#define CP11X_PCIE1_BASE       f6620000
+#define CP11X_PCIE2_BASE       f6640000
+
+#include "armada-cp115.dtsi"
+
+#undef CP11X_NAME
+#undef CP11X_BASE
+#undef CP11X_PCIEx_MEM_BASE
+#undef CP11X_PCIEx_MEM_SIZE
+#undef CP11X_PCIE0_BASE
+#undef CP11X_PCIE1_BASE
+#undef CP11X_PCIE2_BASE
+
+&cp2_crypto {
+       status = "disabled";
+};
+
+&cp2_ethernet {
+       status = "okay";
+};
+
+/* SLM-1521-V2, CON9 */
+&cp2_eth0 {
+       status = "disabled";
+       phy-mode = "10gbase-kr";
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp2_comphy4 0>;
+       managed = "in-band-status";
+       sfp = <&cp2_sfp_eth0>;
+};
+
+&cp2_gpio1 {
+       status = "okay";
+};
+
+&cp2_gpio2 {
+       status = "okay";
+};
+
+&cp2_i2c0 {
+       clock-frequency = <100000>;
+
+       /* SLM-1521-V2 - U3 */
+       i2c-mux@72 {
+               compatible = "nxp,pca9544";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x72>;
+               cp2_sfpp0_i2c: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+                       /* U12 */
+                       cp2_module_expander1: pca9555@21 {
+                               compatible = "nxp,pca9555";
+                               pinctrl-names = "default";
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               reg = <0x21>;
+                       };
+               };
+       };
+};
+
+/* SLM-1521-V2, CON6 */
+&cp2_pcie0 {
+       status = "okay";
+       num-lanes = <2>;
+       num-viewport = <8>;
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp2_comphy0 0
+               &cp2_comphy1 0>;
+};
+
+/* SLM-1521-V2, CON8 */
+&cp2_pcie2 {
+       status = "okay";
+       num-lanes = <1>;
+       num-viewport = <8>;
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp2_comphy5 2>;
+};
+
+&cp2_sata0 {
+       status = "okay";
+
+       /* SLM-1521-V2, CON4 */
+       sata-port@0 {
+               /* Generic PHY, providing serdes lanes */
+               phys = <&cp2_comphy2 0>;
+       };
+};
+
+/* CON 2 on SLM-1683 - microSD */
+&cp2_sdhci0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp2_sdhci_pins>;
+       bus-width = <4>;
+       cd-gpios = <&cp2_gpio2 23 GPIO_ACTIVE_LOW>;
+       vqmmc-supply = <&cp2_reg_sd_vccq>;
+};
+
+&cp2_syscon0 {
+       cp2_pinctrl: pinctrl {
+               compatible = "marvell,cp115-standalone-pinctrl";
+
+               cp2_i2c0_pins: cp2-i2c-pins-0 {
+                       marvell,pins = "mpp37", "mpp38";
+                       marvell,function = "i2c0";
+               };
+               cp2_sdhci_pins: cp2-sdhi-pins-0 {
+                       marvell,pins = "mpp56", "mpp57", "mpp58",
+                                      "mpp59", "mpp60", "mpp61";
+                       marvell,function = "sdio";
+               };
+       };
+};
+
+&cp2_usb3_0 {
+       status = "okay";
+       usb-phy = <&cp2_usb3_0_phy0>;
+       phy-names = "usb";
+};
+
+/* SLM-1521-V2, CON11 */
+&cp2_usb3_1 {
+       status = "okay";
+       usb-phy = <&cp2_usb3_0_phy1>;
+       phy-names = "usb";
+       /* Generic PHY, providing serdes lanes */
+       phys = <&cp2_comphy3 1>;
+};
index 97f84aa..10b3247 100644 (file)
                        clock-names = "spi", "wrap";
                };
 
+               systimer: timer@10017000 {
+                       compatible = "mediatek,mt8183-timer",
+                                    "mediatek,mt6765-timer";
+                       reg = <0 0x10017000 0 0x1000>;
+                       interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&topckgen CLK_TOP_CLK13M>;
+                       clock-names = "clk13m";
+               };
+
                auxadc: auxadc@11001000 {
                        compatible = "mediatek,mt8183-auxadc",
                                     "mediatek,mt8173-auxadc";
index bdace01..f1de4ff 100644 (file)
        };
 
        padctl@3520000 {
-               status = "disabled";
+               status = "okay";
 
                avdd-pll-erefeut-supply = <&vdd_1v8_pll>;
                avdd-usb-supply = <&vdd_3v3_sys>;
        };
 
        usb@3530000 {
-               status = "disabled";
+               status = "okay";
 
                phys = <&{/padctl@3520000/pads/usb2/lanes/usb2-0}>,
                       <&{/padctl@3520000/pads/usb2/lanes/usb2-1}>,
                        status = "disabled";
                };
 
+               /* DP on E3320 */
                sor@15540000 {
-                       status = "disabled";
+                       status = "okay";
+
+                       avdd-io-hdmi-dp-supply = <&vdd_hdmi_1v05>;
+                       vdd-hdmi-dp-pll = <&vdd_1v8_ap>;
 
-                       nvidia,dpaux = <&dpaux1>;
+                       nvidia,dpaux = <&dpaux>;
                };
 
                sor@15580000 {
index 47cd831..7893d78 100644 (file)
                      <0x0 0x03538000 0x0 0x1000>;
                reg-names = "hcd", "fpci";
 
+               iommus = <&smmu TEGRA186_SID_XUSB_HOST>;
                interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
                        reset-names = "vic";
 
                        power-domains = <&bpmp TEGRA186_POWER_DOMAIN_VIC>;
+                       iommus = <&smmu TEGRA186_SID_VIC>;
                };
 
                dsib: dsi@15400000 {
                };
 
                sor1: sor@15580000 {
-                       compatible = "nvidia,tegra186-sor1";
+                       compatible = "nvidia,tegra186-sor";
                        reg = <0x15580000 0x10000>;
                        interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&bpmp TEGRA186_CLK_SOR1>,
index 4c38426..c7f2a20 100644 (file)
@@ -8,17 +8,18 @@
        compatible = "nvidia,p2888", "nvidia,tegra194";
 
        aliases {
-               sdhci0 = "/cbb/sdhci@3460000";
-               sdhci1 = "/cbb/sdhci@3400000";
+               ethernet0 = "/cbb@0/ethernet@2490000";
+               sdhci0 = "/cbb@0/sdhci@3460000";
+               sdhci1 = "/cbb@0/sdhci@3400000";
                serial0 = &tcu;
                i2c0 = "/bpmp/i2c";
-               i2c1 = "/cbb/i2c@3160000";
-               i2c2 = "/cbb/i2c@c240000";
-               i2c3 = "/cbb/i2c@3180000";
-               i2c4 = "/cbb/i2c@3190000";
-               i2c5 = "/cbb/i2c@31c0000";
-               i2c6 = "/cbb/i2c@c250000";
-               i2c7 = "/cbb/i2c@31e0000";
+               i2c1 = "/cbb@0/i2c@3160000";
+               i2c2 = "/cbb@0/i2c@c240000";
+               i2c3 = "/cbb@0/i2c@3180000";
+               i2c4 = "/cbb@0/i2c@3190000";
+               i2c5 = "/cbb@0/i2c@31c0000";
+               i2c6 = "/cbb@0/i2c@c250000";
+               i2c7 = "/cbb@0/i2c@31e0000";
        };
 
        chosen {
@@ -26,7 +27,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       cbb {
+       cbb@0 {
                ethernet@2490000 {
                        status = "okay";
 
                                        in-ldo7-8-supply = <&vdd_1v8ls>;
 
                                        vdd_1v0: sd0 {
-                                               regulator-name = "VDD_1V0";
+                                               regulator-name = "VDDIO_SYS_1V0";
                                                regulator-min-microvolt = <1000000>;
                                                regulator-max-microvolt = <1000000>;
                                                regulator-always-on;
                                        };
 
                                        vdd_1v8hs: sd1 {
-                                               regulator-name = "VDD_1V8HS";
+                                               regulator-name = "VDDIO_SYS_1V8HS";
                                                regulator-min-microvolt = <1800000>;
                                                regulator-max-microvolt = <1800000>;
                                                regulator-always-on;
                                        };
 
                                        vdd_1v8ls: sd2 {
-                                               regulator-name = "VDD_1V8LS";
+                                               regulator-name = "VDDIO_SYS_1V8LS";
                                                regulator-min-microvolt = <1800000>;
                                                regulator-max-microvolt = <1800000>;
                                                regulator-always-on;
                                        };
 
                                        vdd_1v8ao: sd3 {
-                                               regulator-name = "VDD_1V8AO";
+                                               regulator-name = "VDDIO_AO_1V8";
                                                regulator-min-microvolt = <1800000>;
                                                regulator-max-microvolt = <1800000>;
                                                regulator-always-on;
                                        };
 
                                        ldo2 {
-                                               regulator-name = "VDD_AO_3V3";
+                                               regulator-name = "VDDIO_AO_3V3";
                                                regulator-min-microvolt = <3300000>;
                                                regulator-max-microvolt = <3300000>;
                                                regulator-always-on;
                                        };
 
                                        ldo7 {
-                                               regulator-name = "VDD_CSI_1V2";
+                                               regulator-name = "AVDD_CSI_1V2";
                                                regulator-min-microvolt = <1200000>;
                                                regulator-max-microvolt = <1200000>;
                                        };
                        regulator-name = "VDD_12V";
                        regulator-min-microvolt = <1200000>;
                        regulator-max-microvolt = <1200000>;
-                       gpio = <&gpio TEGRA194_MAIN_GPIO(A, 1) GPIO_ACTIVE_LOW>;
+                       gpio = <&gpio TEGRA194_MAIN_GPIO(A, 1) GPIO_ACTIVE_HIGH>;
                        regulator-boot-on;
-                       enable-active-low;
                };
        };
 };
index d47cd8c..353a6a2 100644 (file)
@@ -10,8 +10,8 @@
        model = "NVIDIA Jetson AGX Xavier Developer Kit";
        compatible = "nvidia,p2972-0000", "nvidia,tegra194";
 
-       cbb {
-               aconnect {
+       cbb@0 {
+               aconnect@2900000 {
                        status = "okay";
 
                        dma-controller@2930000 {
                                status = "okay";
                        };
 
+                       dpaux@155c0000 {
+                               status = "okay";
+                       };
+
+                       dpaux@155d0000 {
+                               status = "okay";
+                       };
+
                        dpaux@155e0000 {
                                status = "okay";
                        };
 
+                       /* DP0 */
+                       sor@15b00000 {
+                               status = "okay";
+
+                               avdd-io-hdmi-dp-supply = <&vdd_1v0>;
+                               vdd-hdmi-dp-pll-supply = <&vdd_1v8hs>;
+
+                               nvidia,dpaux = <&dpaux0>;
+                       };
+
+                       /* DP1 */
+                       sor@15b40000 {
+                               status = "okay";
+
+                               avdd-io-hdmi-dp-supply = <&vdd_1v0>;
+                               vdd-hdmi-dp-pll-supply = <&vdd_1v8hs>;
+
+                               nvidia,dpaux = <&dpaux1>;
+                       };
+
+                       /* HDMI */
                        sor@15b80000 {
                                status = "okay";
 
index 3c0cf54..11220d9 100644 (file)
@@ -15,7 +15,7 @@
        #size-cells = <2>;
 
        /* control backbone */
-       cbb {
+       cbb@0 {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
@@ -39,7 +39,8 @@
                };
 
                ethernet@2490000 {
-                       compatible = "nvidia,tegra186-eqos",
+                       compatible = "nvidia,tegra194-eqos",
+                                    "nvidia,tegra186-eqos",
                                     "snps,dwc-qos-ethernet-4.10";
                        reg = <0x02490000 0x10000>;
                        interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
@@ -60,7 +61,7 @@
                        snps,rxpbl = <8>;
                };
 
-               aconnect {
+               aconnect@2900000 {
                        compatible = "nvidia,tegra194-aconnect",
                                     "nvidia,tegra210-aconnect";
                        clocks = <&bpmp TEGRA194_CLK_APE>,
 
                        sor1: sor@15b40000 {
                                compatible = "nvidia,tegra194-sor";
-                               reg = <0x155c0000 0x40000>;
+                               reg = <0x15b40000 0x40000>;
                                interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&bpmp TEGRA194_CLK_SOR1_REF>,
                                         <&bpmp TEGRA194_CLK_SOR1_OUT>,
 
                nvidia,bpmp = <&bpmp 1>;
 
-               supports-clkreq;
                nvidia,aspm-cmrt-us = <60>;
                nvidia,aspm-pwr-on-t-us = <20>;
                nvidia,aspm-l0s-entrance-latency-us = <3>;
 
                nvidia,bpmp = <&bpmp 2>;
 
-               supports-clkreq;
                nvidia,aspm-cmrt-us = <60>;
                nvidia,aspm-pwr-on-t-us = <20>;
                nvidia,aspm-l0s-entrance-latency-us = <3>;
 
                nvidia,bpmp = <&bpmp 3>;
 
-               supports-clkreq;
                nvidia,aspm-cmrt-us = <60>;
                nvidia,aspm-pwr-on-t-us = <20>;
                nvidia,aspm-l0s-entrance-latency-us = <3>;
 
                nvidia,bpmp = <&bpmp 4>;
 
-               supports-clkreq;
                nvidia,aspm-cmrt-us = <60>;
                nvidia,aspm-pwr-on-t-us = <20>;
                nvidia,aspm-l0s-entrance-latency-us = <3>;
 
                nvidia,bpmp = <&bpmp 0>;
 
-               supports-clkreq;
                nvidia,aspm-cmrt-us = <60>;
                nvidia,aspm-pwr-on-t-us = <20>;
                nvidia,aspm-l0s-entrance-latency-us = <3>;
                interrupt-map-mask = <0 0 0 0>;
                interrupt-map = <0 0 0 0 &gic GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 
-               supports-clkreq;
                nvidia,aspm-cmrt-us = <60>;
                nvidia,aspm-pwr-on-t-us = <20>;
                nvidia,aspm-l0s-entrance-latency-us = <3>;
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               cpu0_0: cpu@0 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
-                       reg = <0x10000>;
+                       reg = <0x000>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_0>;
                };
 
-               cpu@1 {
+               cpu0_1: cpu@1 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
-                       reg = <0x10001>;
+                       reg = <0x001>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_0>;
                };
 
-               cpu@2 {
+               cpu1_0: cpu@100 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
                        reg = <0x100>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_1>;
                };
 
-               cpu@3 {
+               cpu1_1: cpu@101 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
                        reg = <0x101>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_1>;
                };
 
-               cpu@4 {
+               cpu2_0: cpu@200 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
                        reg = <0x200>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_2>;
                };
 
-               cpu@5 {
+               cpu2_1: cpu@201 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
                        reg = <0x201>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_2>;
                };
 
-               cpu@6 {
+               cpu3_0: cpu@300 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
-                       reg = <0x10300>;
+                       reg = <0x300>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_3>;
                };
 
-               cpu@7 {
+               cpu3_1: cpu@301 {
                        compatible = "nvidia,tegra194-carmel";
                        device_type = "cpu";
-                       reg = <0x10301>;
+                       reg = <0x301>;
                        enable-method = "psci";
+                       i-cache-size = <131072>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <512>;
+                       d-cache-size = <65536>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <256>;
+                       next-level-cache = <&l2c_3>;
+               };
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0_0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu0_1>;
+                               };
+                       };
+
+                       cluster1 {
+                               core0 {
+                                       cpu = <&cpu1_0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu1_1>;
+                               };
+                       };
+
+                       cluster2 {
+                               core0 {
+                                       cpu = <&cpu2_0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu2_1>;
+                               };
+                       };
+
+                       cluster3 {
+                               core0 {
+                                       cpu = <&cpu3_0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu3_1>;
+                               };
+                       };
+               };
+
+               l2c_0: l2-cache0 {
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
+                       next-level-cache = <&l3c>;
+               };
+
+               l2c_1: l2-cache1 {
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
+                       next-level-cache = <&l3c>;
+               };
+
+               l2c_2: l2-cache2 {
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
+                       next-level-cache = <&l3c>;
+               };
+
+               l2c_3: l2-cache3 {
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
+                       next-level-cache = <&l3c>;
+               };
+
+               l3c: l3-cache {
+                       cache-size = <4194304>;
+                       cache-line-size = <64>;
+                       cache-sets = <4096>;
                };
        };
 
index 2772382..cb58f79 100644 (file)
 
        pmc@7000e400 {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <0>;
+               nvidia,cpu-pwr-good-time = <0>;
+               nvidia,cpu-pwr-off-time = <0>;
+               nvidia,core-pwr-good-time = <4587 3876>;
+               nvidia,core-pwr-off-time = <39065>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
        };
 
        /* eMMC */
index a7dc319..b009507 100644 (file)
                        regulator-name = "VDD_HDMI_5V0";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
-                       gpio = <&exp1 12 GPIO_ACTIVE_LOW>;
+                       gpio = <&exp1 12 GPIO_ACTIVE_HIGH>;
                        enable-active-high;
                        vin-supply = <&vdd_5v0_sys>;
                };
index 9d17ec7..90381d5 100644 (file)
                        status = "okay";
                };
 
+               sor@54540000 {
+                       status = "okay";
+
+                       avdd-io-hdmi-dp-supply = <&avdd_io_edp_1v05>;
+                       vdd-hdmi-dp-pll-supply = <&vdd_1v8>;
+
+                       nvidia,xbar-cfg = <2 1 0 3 4>;
+                       nvidia,dpaux = <&dpaux>;
+               };
+
                sor@54580000 {
                        status = "okay";
 
                                           GPIO_ACTIVE_LOW>;
                        nvidia,xbar-cfg = <0 1 2 3 4>;
                };
+
+               dpaux@545c0000 {
+                       status = "okay";
+               };
        };
 
        gpu@57000000 {
 
        pmc@7000e400 {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <0>;
+               nvidia,cpu-pwr-good-time = <0>;
+               nvidia,cpu-pwr-off-time = <0>;
+               nvidia,core-pwr-good-time = <4587 3876>;
+               nvidia,core-pwr-off-time = <39065>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
        };
 
        hda@70030000 {
                        enable-gpios = <&pmic 6 GPIO_ACTIVE_HIGH>;
                        vin-supply = <&vdd_5v0_sys>;
                };
+
+               avdd_io_edp_1v05: regulator@7 {
+                       compatible = "regulator-fixed";
+                       reg = <7>;
+
+                       regulator-name = "AVDD_IO_EDP_1V05";
+                       regulator-min-microvolt = <1050000>;
+                       regulator-max-microvolt = <1050000>;
+
+                       gpio = <&pmic 7 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+
+                       vin-supply = <&avdd_1v05_pll>;
+               };
        };
 };
index 6597531..48c6325 100644 (file)
                        reg = <0x0 0x54540000 0x0 0x00040000>;
                        interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&tegra_car TEGRA210_CLK_SOR0>,
+                                <&tegra_car TEGRA210_CLK_SOR0_OUT>,
                                 <&tegra_car TEGRA210_CLK_PLL_D_OUT0>,
                                 <&tegra_car TEGRA210_CLK_PLL_DP>,
                                 <&tegra_car TEGRA210_CLK_SOR_SAFE>;
-                       clock-names = "sor", "parent", "dp", "safe";
+                       clock-names = "sor", "out", "parent", "dp", "safe";
                        resets = <&tegra_car 182>;
                        reset-names = "sor";
                        pinctrl-0 = <&state_dpaux_aux>;
        rtc@7000e000 {
                compatible = "nvidia,tegra210-rtc", "nvidia,tegra20-rtc";
                reg = <0x0 0x7000e000 0x0 0x100>;
-               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-parent = <&pmc>;
                clocks = <&tegra_car TEGRA210_CLK_RTC>;
                clock-names = "rtc";
        };
                reg = <0x0 0x7000e400 0x0 0x400>;
                clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
                clock-names = "pclk", "clk32k_in";
+               #interrupt-cells = <2>;
+               interrupt-controller;
 
                powergates {
                        pd_audio: aud {
                };
        };
 
+       pmu {
+               compatible = "arm,armv8-pmuv3";
+               interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&{/cpus/cpu@0} &{/cpus/cpu@1}
+                                     &{/cpus/cpu@2} &{/cpus/cpu@3}>;
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 13
                reg = <0x0 0x700e2000 0x0 0x600 /* SOC_THERM reg_base */
                        0x0 0x60006000 0x0 0x400>; /* CAR reg_base */
                reg-names = "soctherm-reg", "car-reg";
-               interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "thermal", "edp";
                clocks = <&tegra_car TEGRA210_CLK_TSENSOR>,
                        <&tegra_car TEGRA210_CLK_SOC_THERM>;
                clock-names = "tsensor", "soctherm";
                                };
                        };
                };
+
                mem {
                        polling-delay-passive = <0>;
                        polling-delay = <0>;
                                 */
                        };
                };
+
                gpu {
                        polling-delay-passive = <1000>;
                        polling-delay = <0>;
                                };
                        };
                };
+
                pllx {
                        polling-delay-passive = <0>;
                        polling-delay = <0>;
index 04ad2fb..dba3488 100644 (file)
                                l21 {
                                        regulator-min-microvolt = <2950000>;
                                        regulator-max-microvolt = <2950000>;
+                                       regulator-allow-set-load;
+                                       regulator-system-load = <200000>;
                                };
                                l22 {
                                        regulator-min-microvolt = <3300000>;
index 2b28e38..d1ccb94 100644 (file)
@@ -5,6 +5,7 @@
 #include "msm8916.dtsi"
 #include "pm8916.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
        model = "Longcheer L8150";
                stdout-path = "serial0";
        };
 
+       reserved-memory {
+               // wcnss.mdt is not relocatable, so it must be loaded at 0x8b600000
+               /delete-node/ wcnss@89300000;
+
+               wcnss_mem: wcnss@8b600000 {
+                       reg = <0x0 0x8b600000 0x0 0x600000>;
+                       no-map;
+               };
+       };
+
        soc {
                sdhci@7824000 {
                        status = "okay";
                        };
                };
 
+               wcnss@a21b000 {
+                       status = "okay";
+               };
+
                /*
                 * Attempting to enable these devices causes a "synchronous
                 * external abort". Suspected cause is that the debug power
                pinctrl-names = "default";
                pinctrl-0 = <&usb_vbus_default>;
        };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys_default>;
+
+               label = "GPIO Buttons";
+
+               volume-up {
+                       label = "Volume Up";
+                       gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+       };
 };
 
 &msmgpio {
+       gpio_keys_default: gpio_keys_default {
+               pinmux {
+                       function = "gpio";
+                       pins = "gpio107";
+               };
+               pinconf {
+                       pins = "gpio107";
+                       drive-strength = <2>;
+                       bias-pull-up;
+               };
+       };
+
        usb_vbus_default: usb-vbus-default {
                pinmux {
                        function = "gpio";
        };
 };
 
+&spmi_bus {
+       pm8916@0 {
+               pon@800 {
+                       volume-down {
+                               compatible = "qcom,pm8941-resin";
+                               interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+                               bias-pull-up;
+                               linux,code = <KEY_VOLUMEDOWN>;
+                       };
+               };
+       };
+};
+
 &smd_rpm_regulators {
        vdd_l1_l2_l3-supply = <&pm8916_s3>;
        vdd_l4_l5_l6-supply = <&pm8916_s4>;
index e675ff4..bd1eb3e 100644 (file)
@@ -3,6 +3,7 @@
 #include "msm8916.dtsi"
 #include "pm8916.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
 / {
                        };
                };
 
+               wcnss@a21b000 {
+                       status = "okay";
+               };
+
                /*
                 * Attempting to enable these devices causes a "synchronous
                 * external abort". Suspected cause is that the debug power
                etm@85f000 { status = "disabled"; };
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys_default>;
+
+               label = "GPIO Buttons";
+
+               volume-up {
+                       label = "Volume Up";
+                       gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+
+               home {
+                       label = "Home";
+                       gpios = <&msmgpio 109 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_HOMEPAGE>;
+               };
+       };
+
+       gpio-hall-sensor {
+               compatible = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_hall_sensor_default>;
+
+               label = "GPIO Hall Effect Sensor";
+
+               hall-sensor {
+                       label = "Hall Effect Sensor";
+                       gpios = <&msmgpio 52 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <EV_SW>;
+                       linux,code = <SW_LID>;
+                       linux,can-disable;
+               };
+       };
+
        i2c-muic {
                compatible = "i2c-gpio";
                sda-gpios = <&msmgpio 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
 };
 
 &msmgpio {
+       gpio_keys_default: gpio_keys_default {
+               pinmux {
+                       function = "gpio";
+                       pins = "gpio107", "gpio109";
+               };
+               pinconf {
+                       pins = "gpio107", "gpio109";
+                       drive-strength = <2>;
+                       bias-pull-up;
+               };
+       };
+
+       gpio_hall_sensor_default: gpio_hall_sensor_default {
+               pinmux {
+                       function = "gpio";
+                       pins = "gpio52";
+               };
+               pinconf {
+                       pins = "gpio52";
+                       drive-strength = <2>;
+                       bias-disable;
+               };
+       };
+
        muic_int_default: muic_int_default {
                pinmux {
                        function = "gpio";
                regulator-max-microvolt = <2700000>;
        };
 };
+
+&spmi_bus {
+       pm8916@0 {
+               pon@800 {
+                       volume-down {
+                               compatible = "qcom,pm8941-resin";
+                               interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+                               bias-pull-up;
+                               linux,code = <KEY_VOLUMEDOWN>;
+                       };
+               };
+       };
+};
index 1aa59da..6629a62 100644 (file)
@@ -8,3 +8,9 @@
        model = "Samsung Galaxy A5U (EUR)";
        compatible = "samsung,a5u-eur", "qcom,msm8916";
 };
+
+&pronto {
+       iris {
+               compatible = "qcom,wcn3680";
+       };
+};
index 5ea9fb8..8686e10 100644 (file)
                        polling-delay-passive = <250>;
                        polling-delay = <1000>;
 
-                       thermal-sensors = <&tsens 4>;
+                       thermal-sensors = <&tsens 5>;
 
                        trips {
                                cpu0_1_alert0: trip-point@0 {
                        polling-delay-passive = <250>;
                        polling-delay = <1000>;
 
-                       thermal-sensors = <&tsens 3>;
+                       thermal-sensors = <&tsens 4>;
 
                        trips {
                                cpu2_3_alert0: trip-point@0 {
index 87f4d9c..4ca2e7b 100644 (file)
                        reg = <0x4a9000 0x1000>, /* TM */
                              <0x4a8000 0x1000>; /* SROT */
                        #qcom,sensors = <13>;
+                       interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
                        reg = <0x4ad000 0x1000>, /* TM */
                              <0x4ac000 0x1000>; /* SROT */
                        #qcom,sensors = <8>;
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
index 9682d4d..6138b58 100644 (file)
        };
 };
 
+&blsp1_uart3 {
+       status = "okay";
+
+       bluetooth {
+               compatible = "qcom,wcn3990-bt";
+
+               vddio-supply = <&vreg_s4a_1p8>;
+               vddxo-supply = <&vreg_l7a_1p8>;
+               vddrf-supply = <&vreg_l17a_1p3>;
+               vddch0-supply = <&vreg_l25a_3p3>;
+               max-speed = <3200000>;
+       };
+};
+
+/*
+ * The laptop FW does not appear to support the retention state as it is
+ * not advertised as enabled in ACPI, and enabling it in DT can cause boot
+ * hangs.
+ */
+&CPU0 {
+       cpu-idle-states = <&LITTLE_CPU_SLEEP_1>;
+};
+
+&CPU1 {
+       cpu-idle-states = <&LITTLE_CPU_SLEEP_1>;
+};
+
+&CPU2 {
+       cpu-idle-states = <&LITTLE_CPU_SLEEP_1>;
+};
+
+&CPU3 {
+       cpu-idle-states = <&LITTLE_CPU_SLEEP_1>;
+};
+
+&CPU4 {
+       cpu-idle-states = <&BIG_CPU_SLEEP_1>;
+};
+
+&CPU5 {
+       cpu-idle-states = <&BIG_CPU_SLEEP_1>;
+};
+
+&CPU6 {
+       cpu-idle-states = <&BIG_CPU_SLEEP_1>;
+};
+
+&CPU7 {
+       cpu-idle-states = <&BIG_CPU_SLEEP_1>;
+};
+
 &qusb2phy {
        status = "okay";
 
                vreg_l7a_1p8: l7 {
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
+                       regulator-allow-set-load;
                };
                vreg_l8a_1p2: l8 {
                        regulator-min-microvolt = <1200000>;
                vreg_l17a_1p3: l17 {
                        regulator-min-microvolt = <1304000>;
                        regulator-max-microvolt = <1304000>;
+                       regulator-allow-set-load;
                };
                vreg_l18a_2p7: l18 {
                        regulator-min-microvolt = <2704000>;
                vreg_l25a_3p3: l25 {
                        regulator-min-microvolt = <3104000>;
                        regulator-max-microvolt = <3312000>;
+                       regulator-allow-set-load;
                };
                vreg_l26a_1p2: l26 {
                        regulator-min-microvolt = <1200000>;
index 108667c..5f101a2 100644 (file)
        };
 };
 
+&blsp1_uart3 {
+       status = "okay";
+
+       bluetooth {
+               compatible = "qcom,wcn3990-bt";
+
+               vddio-supply = <&vreg_s4a_1p8>;
+               vddxo-supply = <&vreg_l7a_1p8>;
+               vddrf-supply = <&vreg_l17a_1p3>;
+               vddch0-supply = <&vreg_l25a_3p3>;
+               max-speed = <3200000>;
+       };
+};
+
 &blsp2_uart1 {
        status = "okay";
 };
 
+&etf {
+       status = "okay";
+};
+
+&etm1 {
+       status = "okay";
+};
+
+&etm2 {
+       status = "okay";
+};
+
+&etm3 {
+       status = "okay";
+};
+
+&etm4 {
+       status = "okay";
+};
+
+&etm5 {
+       status = "okay";
+};
+
+&etm6 {
+       status = "okay";
+};
+
+&etm7 {
+       status = "okay";
+};
+
+&etm8 {
+       status = "okay";
+};
+
+&etr {
+       status = "okay";
+};
+
+&funnel1 {
+       status = "okay";
+};
+
+&funnel2 {
+       status = "okay";
+};
+
+&funnel3 {
+       status = "okay";
+};
+
+&funnel4 {
+       status = "okay";
+};
+
+&funnel5 {
+       status = "okay";
+};
+
 &pm8005_lsid1 {
        pm8005-regulators {
                compatible = "qcom,pm8005-regulators";
        vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
 };
 
+&replicator1 {
+       status = "okay";
+};
+
 &rpm_requests {
        pm8998-regulators {
                compatible = "qcom,rpm-pm8998-regulators";
        pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
 };
 
+&stm {
+       status = "okay";
+};
+
 &ufshc {
        vcc-supply = <&vreg_l20a_2p95>;
        vccq-supply = <&vreg_l26a_1p2>;
index 6db70ac..e32d3ab 100644 (file)
                        drive-strength = <2>;   /* 2 mA */
                };
        };
+
+       blsp1_uart3_on: blsp1_uart3_on {
+               mux {
+                       pins = "gpio45", "gpio46", "gpio47", "gpio48";
+                       function = "blsp_uart3_a";
+               };
+
+               config {
+                       pins = "gpio45", "gpio46", "gpio47", "gpio48";
+                       drive-strength = <2>;
+                       bias-disable;
+               };
+       };
 };
index c6f8143..fc7838e 100644 (file)
                        compatible = "qcom,msm8998-tsens", "qcom,tsens-v2";
                        reg = <0x010ab000 0x1000>, /* TM */
                              <0x010aa000 0x1000>; /* SROT */
-
                        #qcom,sensors = <14>;
+                       interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
                        compatible = "qcom,msm8998-tsens", "qcom,tsens-v2";
                        reg = <0x010ae000 0x1000>, /* TM */
                              <0x010ad000 0x1000>; /* SROT */
-
                        #qcom,sensors = <8>;
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
                        #interrupt-cells = <0x2>;
                };
 
-               stm@6002000 {
+               stm: stm@6002000 {
                        compatible = "arm,coresight-stm", "arm,primecell";
                        reg = <0x06002000 0x1000>,
                              <0x16280000 0x180000>;
                        reg-names = "stm-base", "stm-data-base";
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               funnel@6041000 {
+               funnel1: funnel@6041000 {
                        compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
                        reg = <0x06041000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               funnel@6042000 {
+               funnel2: funnel@6042000 {
                        compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
                        reg = <0x06042000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               funnel@6045000 {
+               funnel3: funnel@6045000 {
                        compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
                        reg = <0x06045000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               replicator@6046000 {
+               replicator1: replicator@6046000 {
                        compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
                        reg = <0x06046000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etf@6047000 {
+               etf: etf@6047000 {
                        compatible = "arm,coresight-tmc", "arm,primecell";
                        reg = <0x06047000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etr@6048000 {
+               etr: etr@6048000 {
                        compatible = "arm,coresight-tmc", "arm,primecell";
                        reg = <0x06048000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7840000 {
+               etm1: etm@7840000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07840000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7940000 {
+               etm2: etm@7940000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07940000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7a40000 {
+               etm3: etm@7a40000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07a40000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7b40000 {
+               etm4: etm@7b40000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07b40000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               funnel@7b60000 { /* APSS Funnel */
+               funnel4: funnel@7b60000 { /* APSS Funnel */
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07b60000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               funnel@7b70000 {
+               funnel5: funnel@7b70000 {
                        compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
                        reg = <0x07b70000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7c40000 {
+               etm5: etm@7c40000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07c40000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7d40000 {
+               etm6: etm@7d40000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07d40000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7e40000 {
+               etm7: etm@7e40000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07e40000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        };
                };
 
-               etm@7f40000 {
+               etm8: etm@7f40000 {
                        compatible = "arm,coresight-etm4x", "arm,primecell";
                        reg = <0x07f40000 0x1000>;
+                       status = "disabled";
 
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
                        status = "disabled";
                };
 
+               blsp1_dma: dma@c144000 {
+                       compatible = "qcom,bam-v1.7.0";
+                       reg = <0x0c144000 0x25000>;
+                       interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP1_AHB_CLK>;
+                       clock-names = "bam_clk";
+                       #dma-cells = <1>;
+                       qcom,ee = <0>;
+                       qcom,controlled-remotely;
+                       num-channels = <18>;
+                       qcom,num-ees = <4>;
+               };
+
+               blsp1_uart3: serial@c171000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x0c171000 0x1000>;
+                       interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>,
+                                <&gcc GCC_BLSP1_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       dmas = <&blsp1_dma 4>, <&blsp1_dma 5>;
+                       dma-names = "tx", "rx";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&blsp1_uart3_on>;
+                       status = "disabled";
+               };
+
                blsp1_i2c1: i2c@c175000 {
                        compatible = "qcom,i2c-qup-v2.2.1";
                        reg = <0x0c175000 0x600>;
index a97eeb4..f5f0c4c 100644 (file)
                        #clock-cells = <0>;
                        clock-frequency = <19200000>;
                };
+
+               sleep_clk: sleep-clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
        };
 
        cpus {
                        clock-names = "core";
                };
 
+               bimc: interconnect@400000 {
+                       reg = <0x00400000 0x80000>;
+                       compatible = "qcom,qcs404-bimc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
+                               <&rpmcc RPM_SMD_BIMC_A_CLK>;
+               };
+
                tsens: thermal-sensor@4a9000 {
                        compatible = "qcom,qcs404-tsens", "qcom,tsens-v1";
                        reg = <0x004a9000 0x1000>, /* TM */
                        nvmem-cells = <&tsens_caldata>;
                        nvmem-cell-names = "calib";
                        #qcom,sensors = <10>;
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
+               pcnoc: interconnect@500000 {
+                       reg = <0x00500000 0x15080>;
+                       compatible = "qcom,qcs404-pcnoc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_PNOC_CLK>,
+                               <&rpmcc RPM_SMD_PNOC_A_CLK>;
+               };
+
+               snoc: interconnect@580000 {
+                       reg = <0x00580000 0x23080>;
+                       compatible = "qcom,qcs404-snoc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
+                               <&rpmcc RPM_SMD_SNOC_A_CLK>;
+               };
+
                remoteproc_cdsp: remoteproc@b00000 {
                        compatible = "qcom,qcs404-cdsp-pas";
                        reg = <0x00b00000 0x4040>;
                        #mbox-cells = <1>;
                };
 
+               watchdog@b017000 {
+                       compatible = "qcom,kpss-wdt";
+                       reg = <0x0b017000 0x1000>;
+                       clocks = <&sleep_clk>;
+               };
+
                timer@b120000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
index 34881c0..9a4ff57 100644 (file)
 /delete-node/ &venus_mem;
 /delete-node/ &cdsp_mem;
 /delete-node/ &cdsp_pas;
+/delete-node/ &zap_shader;
+/delete-node/ &gpu_mem;
 
 /* Increase the size from 120 MB to 128 MB */
 &mpss_region {
@@ -701,9 +703,8 @@ ap_ts_i2c: &i2c14 {
 
 &ufs_mem_hc {
        status = "okay";
-       pinctrl-names = "init", "default";
-       pinctrl-0 = <&ufs_dev_reset_assert>;
-       pinctrl-1 = <&ufs_dev_reset_deassert>;
+
+       reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>;
 
        vcc-supply = <&src_pp2950_l20a>;
        vcc-max-microamp = <600000>;
@@ -1258,52 +1259,6 @@ ap_ts_i2c: &i2c14 {
                };
        };
 
-       ufs_dev_reset_assert: ufs_dev_reset_assert {
-               config {
-                       pins = "ufs_reset";
-                       bias-pull-down;         /* default: pull down */
-                       /*
-                        * UFS_RESET driver strengths are having
-                        * different values/steps compared to typical
-                        * GPIO drive strengths.
-                        *
-                        * Following table clarifies:
-                        *
-                        * HDRV value | UFS_RESET | Typical GPIO
-                        *   (dec)    |   (mA)    |    (mA)
-                        *     0      |   0.8     |    2
-                        *     1      |   1.55    |    4
-                        *     2      |   2.35    |    6
-                        *     3      |   3.1     |    8
-                        *     4      |   3.9     |    10
-                        *     5      |   4.65    |    12
-                        *     6      |   5.4     |    14
-                        *     7      |   6.15    |    16
-                        *
-                        * POR value for UFS_RESET HDRV is 3 which means
-                        * 3.1mA and we want to use that. Hence just
-                        * specify 8mA to "drive-strength" binding and
-                        * that should result into writing 3 to HDRV
-                        * field.
-                        */
-                       drive-strength = <8>;   /* default: 3.1 mA */
-                       output-low; /* active low reset */
-               };
-       };
-
-       ufs_dev_reset_deassert: ufs_dev_reset_deassert {
-               config {
-                       pins = "ufs_reset";
-                       bias-pull-down;         /* default: pull down */
-                       /*
-                        * default: 3.1 mA
-                        * check comments under ufs_dev_reset_assert
-                        */
-                       drive-strength = <8>;
-                       output-high; /* active low reset */
-               };
-       };
-
        ap_suspend_l_assert: ap_suspend_l_assert {
                config {
                        pins = "gpio126";
index f5a85ca..d100f46 100644 (file)
                        regulator-max-microvolt = <1200000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
+
+               vreg_lvs1a_1p8: lvs1 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vreg_lvs2a_1p8: lvs2 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
        };
 
        pmi8998-rpmh-regulators {
index f406a43..ddb1f23 100644 (file)
 
                        qcom,gmu = <&gmu>;
 
-                       zap-shader {
+                       zap_shader: zap-shader {
                                memory-region = <&gpu_mem>;
                        };
 
                        reg = <0 0x0c263000 0 0x1ff>, /* TM */
                              <0 0x0c222000 0 0x1ff>; /* SROT */
                        #qcom,sensors = <13>;
+                       interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
                        reg = <0 0x0c265000 0 0x1ff>, /* TM */
                              <0 0x0c223000 0 0x1ff>; /* SROT */
                        #qcom,sensors = <8>;
+                       interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
                        status = "disabled";
                };
 
+               watchdog@17980000 {
+                       compatible = "qcom,apss-wdt-sdm845", "qcom,kpss-wdt";
+                       reg = <0 0x17980000 0 0x1000>;
+                       clocks = <&sleep_clk>;
+               };
+
                apss_shared: mailbox@17990000 {
                        compatible = "qcom,sdm845-apss-shared";
                        reg = <0 0x17990000 0 0x1000>;
index ded120d..13dc619 100644 (file)
        };
 };
 
+&adsp_pas {
+       firmware-name = "qcom/LENOVO/81JL/qcadsp850.mbn";
+       status = "okay";
+};
+
 &apps_rsc {
        pm8998-rpmh-regulators {
                compatible = "qcom,pm8998-rpmh-regulators";
        status = "disabled";
 };
 
+&cdsp_pas {
+       firmware-name = "qcom/LENOVO/81JL/qccdsp850.mbn";
+       status = "okay";
+};
+
 &gcc {
        protected-clocks = <GCC_QSPI_CORE_CLK>,
                           <GCC_QSPI_CORE_CLK_SRC>,
        };
 };
 
+&mss_pil {
+       firmware-name = "qcom/LENOVO/81JL/qcdsp1v2850.mbn", "qcom/LENOVO/81JL/qcdsp2850.mbn";
+};
+
 &qup_i2c12_default {
        drive-strength = <2>;
        bias-disable;
index 90c897a..555638a 100644 (file)
@@ -1,4 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+dtb-$(CONFIG_ARCH_REALTEK) += rtd1293-ds418j.dtb
+
 dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-mele-v9.dtb
 dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-probox2-ava.dtb
 dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-zidoo-x9s.dtb
+
+dtb-$(CONFIG_ARCH_REALTEK) += rtd1296-ds418.dtb
diff --git a/arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts b/arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts
new file mode 100644 (file)
index 0000000..b2dd583
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2017 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1293.dtsi"
+
+/ {
+       compatible = "synology,ds418j", "realtek,rtd1293";
+       model = "Synology DiskStation DS418j";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x40000000>;
+       };
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1293.dtsi b/arch/arm64/boot/dts/realtek/rtd1293.dtsi
new file mode 100644 (file)
index 0000000..bd4e227
--- /dev/null
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1293 SoC
+ *
+ * Copyright (c) 2017-2019 Andreas Färber
+ */
+
+#include "rtd129x.dtsi"
+
+/ {
+       compatible = "realtek,rtd1293";
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x0>;
+                       next-level-cache = <&l2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x1>;
+                       next-level-cache = <&l2>;
+               };
+
+               l2: l2-cache {
+                       compatible = "cache";
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+};
+
+&arm_pmu {
+       interrupt-affinity = <&cpu0>, <&cpu1>;
+};
index da19faa..e98e508 100644 (file)
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
 /*
  * Copyright (c) 2016-2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
index 41d7858..93f0e1d 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
 /*
  * Realtek RTD1295 SoC
  *
  * Copyright (c) 2016-2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 #include "rtd129x.dtsi"
diff --git a/arch/arm64/boot/dts/realtek/rtd1296-ds418.dts b/arch/arm64/boot/dts/realtek/rtd1296-ds418.dts
new file mode 100644 (file)
index 0000000..5a051a5
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2017-2019 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1296.dtsi"
+
+/ {
+       compatible = "synology,ds418", "realtek,rtd1296";
+       model = "Synology DiskStation DS418";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x80000000>;
+       };
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1296.dtsi b/arch/arm64/boot/dts/realtek/rtd1296.dtsi
new file mode 100644 (file)
index 0000000..0f9e59c
--- /dev/null
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1296 SoC
+ *
+ * Copyright (c) 2017-2019 Andreas Färber
+ */
+
+#include "rtd129x.dtsi"
+
+/ {
+       compatible = "realtek,rtd1296";
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x0>;
+                       next-level-cache = <&l2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x1>;
+                       next-level-cache = <&l2>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x2>;
+                       next-level-cache = <&l2>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x3>;
+                       next-level-cache = <&l2>;
+               };
+
+               l2: l2-cache {
+                       compatible = "cache";
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                       (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+};
+
+&arm_pmu {
+       interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+};
index b9cb924..4433114 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
 /*
  * Realtek RTD1293/RTD1295/RTD1296 SoC
  *
  * Copyright (c) 2016-2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /memreserve/   0x0000000000000000 0x0000000000030000;
@@ -13,6 +12,7 @@
 /memreserve/   0x0000000001ffe000 0x0000000000004000;
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/realtek,rtd1295.h>
 
 / {
        interrupt-parent = <&gic>;
                interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       osc27M: osc {
+               compatible = "fixed-clock";
+               clock-frequency = <27000000>;
+               #clock-cells = <0>;
+               clock-output-names = "osc27M";
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <1>;
                /* Exclude up to 2 GiB of RAM */
                ranges = <0x80000000 0x80000000 0x80000000>;
 
+               reset1: reset-controller@98000000 {
+                       compatible = "snps,dw-low-reset";
+                       reg = <0x98000000 0x4>;
+                       #reset-cells = <1>;
+               };
+
+               reset2: reset-controller@98000004 {
+                       compatible = "snps,dw-low-reset";
+                       reg = <0x98000004 0x4>;
+                       #reset-cells = <1>;
+               };
+
+               reset3: reset-controller@98000008 {
+                       compatible = "snps,dw-low-reset";
+                       reg = <0x98000008 0x4>;
+                       #reset-cells = <1>;
+               };
+
+               reset4: reset-controller@98000050 {
+                       compatible = "snps,dw-low-reset";
+                       reg = <0x98000050 0x4>;
+                       #reset-cells = <1>;
+               };
+
+               iso_reset: reset-controller@98007088 {
+                       compatible = "snps,dw-low-reset";
+                       reg = <0x98007088 0x4>;
+                       #reset-cells = <1>;
+               };
+
+               wdt: watchdog@98007680 {
+                       compatible = "realtek,rtd1295-watchdog";
+                       reg = <0x98007680 0x100>;
+                       clocks = <&osc27M>;
+               };
+
                uart0: serial@98007800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x98007800 0x400>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clock-frequency = <27000000>;
+                       resets = <&iso_reset RTD1295_ISO_RSTN_UR0>;
                        status = "disabled";
                };
 
@@ -46,6 +90,7 @@
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clock-frequency = <432000000>;
+                       resets = <&reset2 RTD1295_RSTN_UR1>;
                        status = "disabled";
                };
 
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clock-frequency = <432000000>;
+                       resets = <&reset2 RTD1295_RSTN_UR2>;
                        status = "disabled";
                };
 
index 42b74c2..8fdbd22 100644 (file)
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m.dtb
 dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-ex.dtb
+dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n.dtb
+dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-ex.dtb
 dtb-$(CONFIG_ARCH_R8A774C0) += r8a774c0-cat874.dtb r8a774c0-ek874.dtb
 dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb r8a7795-h3ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-kf.dtb
@@ -10,6 +12,10 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-h3ulcb-kf.dtb
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf.dtb
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77960) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb
+dtb-$(CONFIG_ARCH_R8A77960) += r8a7796-m3ulcb-kf.dtb
+dtb-$(CONFIG_ARCH_R8A77960) += r8a7796-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb r8a77965-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
index 3e376d2..2c942a7 100644 (file)
@@ -86,7 +86,7 @@
 
                label = "rcar-sound";
 
-               dais = <&rsnd_port0>;
+               dais = <&rsnd_port>;
        };
 
        vbus0_usb2: regulator-vbus0-usb2 {
 };
 
 &du {
-       clocks = <&cpg CPG_MOD 724>,
-                <&cpg CPG_MOD 723>,
-                <&cpg CPG_MOD 722>,
-                <&versaclock5 1>,
-                <&x302_clk>,
-                <&versaclock5 2>;
-       clock-names = "du.0", "du.1", "du.2",
-                     "dclkin.0", "dclkin.1", "dclkin.2";
        status = "okay";
 };
 
                port@2 {
                        reg = <2>;
                        dw_hdmi0_snd_in: endpoint {
-                               remote-endpoint = <&rsnd_endpoint0>;
+                               remote-endpoint = <&rsnd_endpoint>;
                        };
                };
        };
        /* Single DAI */
        #sound-dai-cells = <0>;
 
-       ports {
-               rsnd_port0: port@0 {
-                       rsnd_endpoint0: endpoint {
-                               remote-endpoint = <&dw_hdmi0_snd_in>;
+       rsnd_port: port {
+               rsnd_endpoint: endpoint {
+                       remote-endpoint = <&dw_hdmi0_snd_in>;
 
-                               dai-format = "i2s";
-                               bitclock-master = <&rsnd_endpoint0>;
-                               frame-master = <&rsnd_endpoint0>;
+                       dai-format = "i2s";
+                       bitclock-master = <&rsnd_endpoint>;
+                       frame-master = <&rsnd_endpoint>;
 
-                               playback = <&ssi2>;
-                       };
+                       playback = <&ssi2>;
                };
        };
 };
index 4280b19..28fe17e 100644 (file)
        chosen {
                bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
        };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm0 0 50000>;
+
+               brightness-levels = <0 2 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+       };
 };
 
 &avb {
        status = "okay";
 };
 
-&pciec0 {
-       status = "okay";
+&gpio1 {
+       /*
+        * When GP1_20 is LOW LVDS0 is connected to the LVDS connector
+        * When GP1_20 is HIGH LVDS0 is connected to the LT8918L
+        */
+       lvds-connector-en-gpio {
+               gpio-hog;
+               gpios = <20 GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "lvds-connector-en-gpio";
+       };
+};
+
+&lvds0 {
+       /*
+        * Please include the LVDS panel .dtsi file and uncomment the below line
+        * to enable LVDS panel connected to RZ/G2[MN] boards.
+        */
+
+       /* status = "okay"; */
+
+       ports {
+               port@1 {
+                       lvds_connector: endpoint {
+                       };
+               };
+       };
 };
 
-&pciec1 {
+&pciec0 {
        status = "okay";
 };
 
                groups = "can1_data";
                function = "can1";
        };
+
+       pwm0_pins: pwm0 {
+               groups = "pwm0";
+               function = "pwm0";
+       };
+};
+
+&pwm0 {
+       pinctrl-0 = <&pwm0_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
 };
index 6e33a3b..c754fca 100644 (file)
@@ -13,3 +13,7 @@
        compatible = "hoperun,hihope-rzg2-ex", "hoperun,hihope-rzg2m",
                     "renesas,r8a774a1";
 };
+
+&pciec1 {
+       status = "okay";
+};
index 93ca973..96f2fb0 100644 (file)
                reg = <0x6 0x00000000 0x0 0x80000000>;
        };
 };
+
+&du {
+       clocks = <&cpg CPG_MOD 724>,
+                <&cpg CPG_MOD 723>,
+                <&cpg CPG_MOD 722>,
+                <&versaclock5 1>,
+                <&x302_clk>,
+                <&versaclock5 2>;
+       clock-names = "du.0", "du.1", "du.2",
+                     "dclkin.0", "dclkin.1", "dclkin.2";
+};
index 06c7c84..34a9f47 100644 (file)
                                      "ssi.1", "ssi.0";
                        status = "disabled";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               port@0 {
-                                       reg = <0>;
-                               };
-                               port@1 {
-                                       reg = <1>;
-                               };
-                       };
-
                        rcar_sound,ctu {
                                ctu00: ctu-0 { };
                                ctu01: ctu-1 { };
                        clock-names = "du.0", "du.1", "du.2";
                        status = "disabled";
 
-                       vsps = <&vspd0 &vspd1 &vspd2>;
+                       vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>;
 
                        ports {
                                #address-cells = <1>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex.dts b/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex.dts
new file mode 100644 (file)
index 0000000..ab47c0b
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the HiHope RZ/G2N sub board
+ *
+ * Copyright (C) 2019 Renesas Electronics Corp.
+ */
+
+#include "r8a774b1-hihope-rzg2n.dts"
+#include "hihope-rzg2-ex.dtsi"
+
+/ {
+       model = "HopeRun HiHope RZ/G2N with sub board";
+       compatible = "hoperun,hihope-rzg2-ex", "hoperun,hihope-rzg2n",
+                    "renesas,r8a774b1";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n.dts b/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n.dts
new file mode 100644 (file)
index 0000000..9910c1a
--- /dev/null
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the HiHope RZ/G2N main board
+ *
+ * Copyright (C) 2019 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a774b1.dtsi"
+#include "hihope-common.dtsi"
+
+/ {
+       model = "HopeRun HiHope RZ/G2N main board based on r8a774b1";
+       compatible = "hoperun,hihope-rzg2n", "renesas,r8a774b1";
+
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0x0 0x48000000 0x0 0x78000000>;
+       };
+
+       memory@480000000 {
+               device_type = "memory";
+               reg = <0x4 0x80000000 0x0 0x80000000>;
+       };
+};
+
+&du {
+       clocks = <&cpg CPG_MOD 724>,
+                <&cpg CPG_MOD 723>,
+                <&cpg CPG_MOD 721>,
+                <&versaclock5 1>,
+                <&x302_clk>,
+                <&versaclock5 2>;
+       clock-names = "du.0", "du.1", "du.3",
+                     "dclkin.0", "dclkin.1", "dclkin.3";
+};
+
+&sdhi3 {
+       mmc-hs400-1_8v;
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
new file mode 100644 (file)
index 0000000..fe78387
--- /dev/null
@@ -0,0 +1,2627 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the r8a774b1 SoC
+ *
+ * Copyright (C) 2019 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r8a774b1-cpg-mssr.h>
+#include <dt-bindings/power/r8a774b1-sysc.h>
+
+/ {
+       compatible = "renesas,r8a774b1";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       /*
+        * The external audio clocks are configured as 0 Hz fixed frequency
+        * clocks by default.
+        * Boards that provide audio clocks should override them.
+        */
+       audio_clk_a: audio_clk_a {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_b: audio_clk_b {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_c: audio_clk_c {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       /* External CAN clock - to be overridden by boards that provide it */
+       can_clk: can {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       cluster0_opp: opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <830000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <830000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1500000000 {
+                       opp-hz = /bits/ 64 <1500000000>;
+                       opp-microvolt = <830000>;
+                       clock-latency-ns = <300000>;
+                       opp-suspend;
+               };
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               a57_0: cpu@0 {
+                       compatible = "arm,cortex-a57";
+                       reg = <0x0>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A774B1_PD_CA57_CPU0>;
+                       next-level-cache = <&L2_CA57>;
+                       enable-method = "psci";
+                       #cooling-cells = <2>;
+                       dynamic-power-coefficient = <854>;
+                       clocks = <&cpg CPG_CORE R8A774B1_CLK_Z>;
+                       operating-points-v2 = <&cluster0_opp>;
+               };
+
+               a57_1: cpu@1 {
+                       compatible = "arm,cortex-a57";
+                       reg = <0x1>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A774B1_PD_CA57_CPU1>;
+                       next-level-cache = <&L2_CA57>;
+                       enable-method = "psci";
+                       clocks = <&cpg CPG_CORE R8A774B1_CLK_Z>;
+                       operating-points-v2 = <&cluster0_opp>;
+               };
+
+               L2_CA57: cache-controller-0 {
+                       compatible = "cache";
+                       power-domains = <&sysc R8A774B1_PD_CA57_SCU>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+       };
+
+       extal_clk: extal {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       extalr_clk: extalr {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       /* External PCIe clock - can be overridden by the board */
+       pcie_bus_clk: pcie_bus {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       pmu_a57 {
+               compatible = "arm,cortex-a57-pmu";
+               interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&a57_0>, <&a57_1>;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0", "arm,psci-0.2";
+               method = "smc";
+       };
+
+       /* External SCIF clock - to be overridden by boards that provide it */
+       scif_clk: scif {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               interrupt-parent = <&gic>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               rwdt: watchdog@e6020000 {
+                       compatible = "renesas,r8a774b1-wdt",
+                                    "renesas,rcar-gen3-wdt";
+                       reg = <0 0xe6020000 0 0x0c>;
+                       clocks = <&cpg CPG_MOD 402>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 402>;
+                       status = "disabled";
+               };
+
+               gpio0: gpio@e6050000 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6050000 0 0x50>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 0 16>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 912>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 912>;
+               };
+
+               gpio1: gpio@e6051000 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6051000 0 0x50>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 32 29>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 911>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 911>;
+               };
+
+               gpio2: gpio@e6052000 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6052000 0 0x50>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 64 15>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 910>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 910>;
+               };
+
+               gpio3: gpio@e6053000 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6053000 0 0x50>;
+                       interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 96 16>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 909>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 909>;
+               };
+
+               gpio4: gpio@e6054000 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6054000 0 0x50>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 128 18>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 908>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 908>;
+               };
+
+               gpio5: gpio@e6055000 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6055000 0 0x50>;
+                       interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 160 26>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 907>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 907>;
+               };
+
+               gpio6: gpio@e6055400 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6055400 0 0x50>;
+                       interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 192 32>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 906>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 906>;
+               };
+
+               gpio7: gpio@e6055800 {
+                       compatible = "renesas,gpio-r8a774b1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6055800 0 0x50>;
+                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 224 4>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 905>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 905>;
+               };
+
+               pfc: pin-controller@e6060000 {
+                       compatible = "renesas,pfc-r8a774b1";
+                       reg = <0 0xe6060000 0 0x50c>;
+               };
+
+               cmt0: timer@e60f0000 {
+                       compatible = "renesas,r8a774b1-cmt0",
+                                    "renesas,rcar-gen3-cmt0";
+                       reg = <0 0xe60f0000 0 0x1004>;
+                       interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 303>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 303>;
+                       status = "disabled";
+               };
+
+               cmt1: timer@e6130000 {
+                       compatible = "renesas,r8a774b1-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6130000 0 0x1004>;
+                       interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 302>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 302>;
+                       status = "disabled";
+               };
+
+               cmt2: timer@e6140000 {
+                       compatible = "renesas,r8a774b1-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6140000 0 0x1004>;
+                       interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 301>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 301>;
+                       status = "disabled";
+               };
+
+               cmt3: timer@e6148000 {
+                       compatible = "renesas,r8a774b1-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6148000 0 0x1004>;
+                       interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 300>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 300>;
+                       status = "disabled";
+               };
+
+               cpg: clock-controller@e6150000 {
+                       compatible = "renesas,r8a774b1-cpg-mssr";
+                       reg = <0 0xe6150000 0 0x1000>;
+                       clocks = <&extal_clk>, <&extalr_clk>;
+                       clock-names = "extal", "extalr";
+                       #clock-cells = <2>;
+                       #power-domain-cells = <0>;
+                       #reset-cells = <1>;
+               };
+
+               rst: reset-controller@e6160000 {
+                       compatible = "renesas,r8a774b1-rst";
+                       reg = <0 0xe6160000 0 0x0200>;
+               };
+
+               sysc: system-controller@e6180000 {
+                       compatible = "renesas,r8a774b1-sysc";
+                       reg = <0 0xe6180000 0 0x0400>;
+                       #power-domain-cells = <1>;
+               };
+
+               tsc: thermal@e6198000 {
+                       compatible = "renesas,r8a774b1-thermal";
+                       reg = <0 0xe6198000 0 0x100>,
+                             <0 0xe61a0000 0 0x100>,
+                             <0 0xe61a8000 0 0x100>;
+                       interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 522>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 522>;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               intc_ex: interrupt-controller@e61c0000 {
+                       compatible = "renesas,intc-ex-r8a774b1", "renesas,irqc";
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <0 0xe61c0000 0 0x200>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 407>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 407>;
+               };
+
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a774b1", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@e6fc0000 {
+                       compatible = "renesas,tmu-r8a774b1", "renesas,tmu";
+                       reg = <0 0xe6fc0000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 124>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 124>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@e6fd0000 {
+                       compatible = "renesas,tmu-r8a774b1", "renesas,tmu";
+                       reg = <0 0xe6fd0000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 123>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 123>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@e6fe0000 {
+                       compatible = "renesas,tmu-r8a774b1", "renesas,tmu";
+                       reg = <0 0xe6fe0000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu4: timer@ffc00000 {
+                       compatible = "renesas,tmu-r8a774b1", "renesas,tmu";
+                       reg = <0 0xffc00000 0 0x30>;
+                       interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@e6500000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774b1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6500000 0 0x40>;
+                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 931>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 931>;
+                       dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+                              <&dmac2 0x91>, <&dmac2 0x90>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@e6508000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774b1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6508000 0 0x40>;
+                       interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 930>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 930>;
+                       dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+                              <&dmac2 0x93>, <&dmac2 0x92>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@e6510000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774b1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6510000 0 0x40>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 929>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 929>;
+                       dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+                              <&dmac2 0x95>, <&dmac2 0x94>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@e66d0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774b1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d0000 0 0x40>;
+                       interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 928>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 928>;
+                       dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@e66d8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774b1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d8000 0 0x40>;
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 927>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 927>;
+                       dmas = <&dmac0 0x99>, <&dmac0 0x98>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@e66e0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774b1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66e0000 0 0x40>;
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 919>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 919>;
+                       dmas = <&dmac0 0x9b>, <&dmac0 0x9a>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c6: i2c@e66e8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774b1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66e8000 0 0x40>;
+                       interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 918>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 918>;
+                       dmas = <&dmac0 0x9d>, <&dmac0 0x9c>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c_dvfs: i2c@e60b0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,iic-r8a774b1",
+                                    "renesas,rcar-gen3-iic",
+                                    "renesas,rmobile-iic";
+                       reg = <0 0xe60b0000 0 0x425>;
+                       interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 926>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 926>;
+                       dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               hscif0: serial@e6540000 {
+                       compatible = "renesas,hscif-r8a774b1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6540000 0 0x60>;
+                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 520>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+                              <&dmac2 0x31>, <&dmac2 0x30>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 520>;
+                       status = "disabled";
+               };
+
+               hscif1: serial@e6550000 {
+                       compatible = "renesas,hscif-r8a774b1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6550000 0 0x60>;
+                       interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 519>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+                              <&dmac2 0x33>, <&dmac2 0x32>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 519>;
+                       status = "disabled";
+               };
+
+               hscif2: serial@e6560000 {
+                       compatible = "renesas,hscif-r8a774b1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6560000 0 0x60>;
+                       interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 518>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+                              <&dmac2 0x35>, <&dmac2 0x34>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 518>;
+                       status = "disabled";
+               };
+
+               hscif3: serial@e66a0000 {
+                       compatible = "renesas,hscif-r8a774b1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe66a0000 0 0x60>;
+                       interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 517>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 517>;
+                       status = "disabled";
+               };
+
+               hscif4: serial@e66b0000 {
+                       compatible = "renesas,hscif-r8a774b1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe66b0000 0 0x60>;
+                       interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 516>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 516>;
+                       status = "disabled";
+               };
+
+               hsusb: usb@e6590000 {
+                       compatible = "renesas,usbhs-r8a774b1",
+                                    "renesas,rcar-gen3-usbhs";
+                       reg = <0 0xe6590000 0 0x200>;
+                       interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 704>, <&cpg CPG_MOD 703>;
+                       dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+                              <&usb_dmac1 0>, <&usb_dmac1 1>;
+                       dma-names = "ch0", "ch1", "ch2", "ch3";
+                       renesas,buswait = <11>;
+                       phys = <&usb2_phy0 3>;
+                       phy-names = "usb";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 704>, <&cpg 703>;
+                       status = "disabled";
+               };
+
+               usb_dmac0: dma-controller@e65a0000 {
+                       compatible = "renesas,r8a774b1-usb-dmac",
+                                    "renesas,usb-dmac";
+                       reg = <0 0xe65a0000 0 0x100>;
+                       interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1";
+                       clocks = <&cpg CPG_MOD 330>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 330>;
+                       #dma-cells = <1>;
+                       dma-channels = <2>;
+               };
+
+               usb_dmac1: dma-controller@e65b0000 {
+                       compatible = "renesas,r8a774b1-usb-dmac",
+                                    "renesas,usb-dmac";
+                       reg = <0 0xe65b0000 0 0x100>;
+                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1";
+                       clocks = <&cpg CPG_MOD 331>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 331>;
+                       #dma-cells = <1>;
+                       dma-channels = <2>;
+               };
+
+               usb3_phy0: usb-phy@e65ee000 {
+                       compatible = "renesas,r8a774b1-usb3-phy",
+                                    "renesas,rcar-gen3-usb3-phy";
+                       reg = <0 0xe65ee000 0 0x90>;
+                       clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
+                                <&usb_extal_clk>;
+                       clock-names = "usb3-if", "usb3s_clk", "usb_extal";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 328>;
+                       #phy-cells = <0>;
+                       status = "disabled";
+               };
+
+               dmac0: dma-controller@e6700000 {
+                       compatible = "renesas,dmac-r8a774b1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe6700000 0 0x10000>;
+                       interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 219>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 219>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+                       iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
+                              <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
+                              <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
+                              <&ipmmu_ds0 6>, <&ipmmu_ds0 7>,
+                              <&ipmmu_ds0 8>, <&ipmmu_ds0 9>,
+                              <&ipmmu_ds0 10>, <&ipmmu_ds0 11>,
+                              <&ipmmu_ds0 12>, <&ipmmu_ds0 13>,
+                              <&ipmmu_ds0 14>, <&ipmmu_ds0 15>;
+               };
+
+               dmac1: dma-controller@e7300000 {
+                       compatible = "renesas,dmac-r8a774b1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe7300000 0 0x10000>;
+                       interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 218>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 218>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
+                              <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
+                              <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
+                              <&ipmmu_ds1 6>, <&ipmmu_ds1 7>,
+                              <&ipmmu_ds1 8>, <&ipmmu_ds1 9>,
+                              <&ipmmu_ds1 10>, <&ipmmu_ds1 11>,
+                              <&ipmmu_ds1 12>, <&ipmmu_ds1 13>,
+                              <&ipmmu_ds1 14>, <&ipmmu_ds1 15>;
+               };
+
+               dmac2: dma-controller@e7310000 {
+                       compatible = "renesas,dmac-r8a774b1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe7310000 0 0x10000>;
+                       interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 217>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 217>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
+                              <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
+                              <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
+                              <&ipmmu_ds1 22>, <&ipmmu_ds1 23>,
+                              <&ipmmu_ds1 24>, <&ipmmu_ds1 25>,
+                              <&ipmmu_ds1 26>, <&ipmmu_ds1 27>,
+                              <&ipmmu_ds1 28>, <&ipmmu_ds1 29>,
+                              <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
+               };
+
+               ipmmu_ds0: mmu@e6740000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xe6740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 0>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ds1: mmu@e7740000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xe7740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 1>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_hc: mmu@e6570000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xe6570000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 2>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mm: mmu@e67b0000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xe67b0000 0 0x1000>;
+                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mp: mmu@ec670000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xec670000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 4>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_pv0: mmu@fd800000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xfd800000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 6>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vc0: mmu@fe6b0000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xfe6b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 12>;
+                       power-domains = <&sysc R8A774B1_PD_A3VC>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi0: mmu@febd0000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xfebd0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 14>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vp0: mmu@fe990000 {
+                       compatible = "renesas,ipmmu-r8a774b1";
+                       reg = <0 0xfe990000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 16>;
+                       power-domains = <&sysc R8A774B1_PD_A3VP>;
+                       #iommu-cells = <1>;
+               };
+
+               avb: ethernet@e6800000 {
+                       compatible = "renesas,etheravb-r8a774b1",
+                                    "renesas,etheravb-rcar-gen3";
+                       reg = <0 0xe6800000 0 0x800>;
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1", "ch2", "ch3",
+                                         "ch4", "ch5", "ch6", "ch7",
+                                         "ch8", "ch9", "ch10", "ch11",
+                                         "ch12", "ch13", "ch14", "ch15",
+                                         "ch16", "ch17", "ch18", "ch19",
+                                         "ch20", "ch21", "ch22", "ch23",
+                                         "ch24";
+                       clocks = <&cpg CPG_MOD 812>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 812>;
+                       phy-mode = "rgmii";
+                       iommus = <&ipmmu_ds0 16>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               can0: can@e6c30000 {
+                       compatible = "renesas,can-r8a774b1",
+                                    "renesas,rcar-gen3-can";
+                       reg = <0 0xe6c30000 0 0x1000>;
+                       interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 916>,
+                                <&cpg CPG_CORE R8A774B1_CLK_CANFD>,
+                                <&can_clk>;
+                       clock-names = "clkp1", "clkp2", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774B1_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 916>;
+                       status = "disabled";
+               };
+
+               can1: can@e6c38000 {
+                       compatible = "renesas,can-r8a774b1",
+                                    "renesas,rcar-gen3-can";
+                       reg = <0 0xe6c38000 0 0x1000>;
+                       interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 915>,
+                                <&cpg CPG_CORE R8A774B1_CLK_CANFD>,
+                                <&can_clk>;
+                       clock-names = "clkp1", "clkp2", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774B1_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 915>;
+                       status = "disabled";
+               };
+
+               canfd: can@e66c0000 {
+                       compatible = "renesas,r8a774b1-canfd",
+                                    "renesas,rcar-gen3-canfd";
+                       reg = <0 0xe66c0000 0 0x8000>;
+                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+                                  <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 914>,
+                                <&cpg CPG_CORE R8A774B1_CLK_CANFD>,
+                                <&can_clk>;
+                       clock-names = "fck", "canfd", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774B1_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 914>;
+                       status = "disabled";
+
+                       channel0 {
+                               status = "disabled";
+                       };
+
+                       channel1 {
+                               status = "disabled";
+                       };
+               };
+
+               pwm0: pwm@e6e30000 {
+                       compatible = "renesas,pwm-r8a774b1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e30000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       status = "disabled";
+               };
+
+               pwm1: pwm@e6e31000 {
+                       compatible = "renesas,pwm-r8a774b1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e31000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       status = "disabled";
+               };
+
+               pwm2: pwm@e6e32000 {
+                       compatible = "renesas,pwm-r8a774b1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e32000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       status = "disabled";
+               };
+
+               pwm3: pwm@e6e33000 {
+                       compatible = "renesas,pwm-r8a774b1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e33000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       status = "disabled";
+               };
+
+               pwm4: pwm@e6e34000 {
+                       compatible = "renesas,pwm-r8a774b1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e34000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       status = "disabled";
+               };
+
+               pwm5: pwm@e6e35000 {
+                       compatible = "renesas,pwm-r8a774b1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e35000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       status = "disabled";
+               };
+
+               pwm6: pwm@e6e36000 {
+                       compatible = "renesas,pwm-r8a774b1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e36000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       status = "disabled";
+               };
+
+               scif0: serial@e6e60000 {
+                       compatible = "renesas,scif-r8a774b1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e60000 0 0x40>;
+                       interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 207>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+                              <&dmac2 0x51>, <&dmac2 0x50>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 207>;
+                       status = "disabled";
+               };
+
+               scif1: serial@e6e68000 {
+                       compatible = "renesas,scif-r8a774b1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e68000 0 0x40>;
+                       interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 206>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+                              <&dmac2 0x53>, <&dmac2 0x52>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 206>;
+                       status = "disabled";
+               };
+
+               scif2: serial@e6e88000 {
+                       compatible = "renesas,scif-r8a774b1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e88000 0 0x40>;
+                       interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 310>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x13>, <&dmac1 0x12>,
+                              <&dmac2 0x13>, <&dmac2 0x12>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 310>;
+                       status = "disabled";
+               };
+
+               scif3: serial@e6c50000 {
+                       compatible = "renesas,scif-r8a774b1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6c50000 0 0x40>;
+                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 204>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 204>;
+                       status = "disabled";
+               };
+
+               scif4: serial@e6c40000 {
+                       compatible = "renesas,scif-r8a774b1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6c40000 0 0x40>;
+                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 203>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 203>;
+                       status = "disabled";
+               };
+
+               scif5: serial@e6f30000 {
+                       compatible = "renesas,scif-r8a774b1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6f30000 0 0x40>;
+                       interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 202>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+                              <&dmac2 0x5b>, <&dmac2 0x5a>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 202>;
+                       status = "disabled";
+               };
+
+               msiof0: spi@e6e90000 {
+                       compatible = "renesas,msiof-r8a774b1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6e90000 0 0x0064>;
+                       interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 211>;
+                       dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+                              <&dmac2 0x41>, <&dmac2 0x40>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 211>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof1: spi@e6ea0000 {
+                       compatible = "renesas,msiof-r8a774b1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6ea0000 0 0x0064>;
+                       interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 210>;
+                       dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+                              <&dmac2 0x43>, <&dmac2 0x42>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 210>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof2: spi@e6c00000 {
+                       compatible = "renesas,msiof-r8a774b1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c00000 0 0x0064>;
+                       interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 209>;
+                       dmas = <&dmac0 0x45>, <&dmac0 0x44>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 209>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof3: spi@e6c10000 {
+                       compatible = "renesas,msiof-r8a774b1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c10000 0 0x0064>;
+                       interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 208>;
+                       dmas = <&dmac0 0x47>, <&dmac0 0x46>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 208>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               vin0: video@e6ef0000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef0000 0 0x1000>;
+                       interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 811>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 811>;
+                       renesas,id = <0>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin0csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin0>;
+                                       };
+                                       vin0csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin0>;
+                                       };
+                               };
+                       };
+               };
+
+               vin1: video@e6ef1000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef1000 0 0x1000>;
+                       interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 810>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 810>;
+                       renesas,id = <1>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin1csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin1>;
+                                       };
+                                       vin1csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin1>;
+                                       };
+                               };
+                       };
+               };
+
+               vin2: video@e6ef2000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef2000 0 0x1000>;
+                       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 809>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 809>;
+                       renesas,id = <2>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin2csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin2>;
+                                       };
+                                       vin2csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin2>;
+                                       };
+                               };
+                       };
+               };
+
+               vin3: video@e6ef3000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef3000 0 0x1000>;
+                       interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 808>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 808>;
+                       renesas,id = <3>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin3csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin3>;
+                                       };
+                                       vin3csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin3>;
+                                       };
+                               };
+                       };
+               };
+
+               vin4: video@e6ef4000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef4000 0 0x1000>;
+                       interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 807>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 807>;
+                       renesas,id = <4>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin4csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin4>;
+                                       };
+                                       vin4csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin4>;
+                                       };
+                               };
+                       };
+               };
+
+               vin5: video@e6ef5000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef5000 0 0x1000>;
+                       interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 806>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 806>;
+                       renesas,id = <5>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin5csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin5>;
+                                       };
+                                       vin5csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin5>;
+                                       };
+                               };
+                       };
+               };
+
+               vin6: video@e6ef6000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef6000 0 0x1000>;
+                       interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 805>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 805>;
+                       renesas,id = <6>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin6csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin6>;
+                                       };
+                                       vin6csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin6>;
+                                       };
+                               };
+                       };
+               };
+
+               vin7: video@e6ef7000 {
+                       compatible = "renesas,vin-r8a774b1";
+                       reg = <0 0xe6ef7000 0 0x1000>;
+                       interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 804>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 804>;
+                       renesas,id = <7>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin7csi20: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&csi20vin7>;
+                                       };
+                                       vin7csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin7>;
+                                       };
+                               };
+                       };
+               };
+
+               rcar_sound: sound@ec500000 {
+                       /*
+                        * #sound-dai-cells is required
+                        *
+                        * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+                        * Multi  DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+                        */
+                       /*
+                        * #clock-cells is required for audio_clkout0/1/2/3
+                        *
+                        * clkout       : #clock-cells = <0>;   <&rcar_sound>;
+                        * clkout0/1/2/3: #clock-cells = <1>;   <&rcar_sound N>;
+                        */
+                       compatible =  "renesas,rcar_sound-r8a774b1", "renesas,rcar_sound-gen3";
+                       reg = <0 0xec500000 0 0x1000>, /* SCU */
+                             <0 0xec5a0000 0 0x100>,  /* ADG */
+                             <0 0xec540000 0 0x1000>, /* SSIU */
+                             <0 0xec541000 0 0x280>,  /* SSI */
+                             <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+                       reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+                       clocks = <&cpg CPG_MOD 1005>,
+                                <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+                                <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+                                <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+                                <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+                                <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+                                <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+                                <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+                                <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+                                <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+                                <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+                                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                                <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+                                <&audio_clk_a>, <&audio_clk_b>,
+                                <&audio_clk_c>,
+                                <&cpg CPG_CORE R8A774B1_CLK_S0D4>;
+                       clock-names = "ssi-all",
+                                     "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+                                     "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+                                     "ssi.1", "ssi.0",
+                                     "src.9", "src.8", "src.7", "src.6",
+                                     "src.5", "src.4", "src.3", "src.2",
+                                     "src.1", "src.0",
+                                     "mix.1", "mix.0",
+                                     "ctu.1", "ctu.0",
+                                     "dvc.0", "dvc.1",
+                                     "clk_a", "clk_b", "clk_c", "clk_i";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 1005>,
+                                <&cpg 1006>, <&cpg 1007>,
+                                <&cpg 1008>, <&cpg 1009>,
+                                <&cpg 1010>, <&cpg 1011>,
+                                <&cpg 1012>, <&cpg 1013>,
+                                <&cpg 1014>, <&cpg 1015>;
+                       reset-names = "ssi-all",
+                                     "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+                                     "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+                                     "ssi.1", "ssi.0";
+                       status = "disabled";
+
+                       rcar_sound,ctu {
+                               ctu00: ctu-0 { };
+                               ctu01: ctu-1 { };
+                               ctu02: ctu-2 { };
+                               ctu03: ctu-3 { };
+                               ctu10: ctu-4 { };
+                               ctu11: ctu-5 { };
+                               ctu12: ctu-6 { };
+                               ctu13: ctu-7 { };
+                       };
+
+                       rcar_sound,dvc {
+                               dvc0: dvc-0 {
+                                       dmas = <&audma1 0xbc>;
+                                       dma-names = "tx";
+                               };
+                               dvc1: dvc-1 {
+                                       dmas = <&audma1 0xbe>;
+                                       dma-names = "tx";
+                               };
+                       };
+
+                       rcar_sound,mix {
+                               mix0: mix-0 { };
+                               mix1: mix-1 { };
+                       };
+
+                       rcar_sound,src {
+                               src0: src-0 {
+                                       interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x85>, <&audma1 0x9a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src1: src-1 {
+                                       interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x87>, <&audma1 0x9c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src2: src-2 {
+                                       interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x89>, <&audma1 0x9e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src3: src-3 {
+                                       interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src4: src-4 {
+                                       interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src5: src-5 {
+                                       interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src6: src-6 {
+                                       interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x91>, <&audma1 0xb4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src7: src-7 {
+                                       interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x93>, <&audma1 0xb6>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src8: src-8 {
+                                       interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x95>, <&audma1 0xb8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src9: src-9 {
+                                       interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x97>, <&audma1 0xba>;
+                                       dma-names = "rx", "tx";
+                               };
+                       };
+
+                       rcar_sound,ssi {
+                               ssi0: ssi-0 {
+                                       interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x01>, <&audma1 0x02>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi1: ssi-1 {
+                                       interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x03>, <&audma1 0x04>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi2: ssi-2 {
+                                       interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x05>, <&audma1 0x06>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi3: ssi-3 {
+                                       interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x07>, <&audma1 0x08>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi4: ssi-4 {
+                                       interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x09>, <&audma1 0x0a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi5: ssi-5 {
+                                       interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0b>, <&audma1 0x0c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi6: ssi-6 {
+                                       interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0d>, <&audma1 0x0e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi7: ssi-7 {
+                                       interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0f>, <&audma1 0x10>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi8: ssi-8 {
+                                       interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x11>, <&audma1 0x12>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi9: ssi-9 {
+                                       interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x13>, <&audma1 0x14>;
+                                       dma-names = "rx", "tx";
+                               };
+                       };
+
+                       rcar_sound,ssiu {
+                               ssiu00: ssiu-0 {
+                                       dmas = <&audma0 0x15>, <&audma1 0x16>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu01: ssiu-1 {
+                                       dmas = <&audma0 0x35>, <&audma1 0x36>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu02: ssiu-2 {
+                                       dmas = <&audma0 0x37>, <&audma1 0x38>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu03: ssiu-3 {
+                                       dmas = <&audma0 0x47>, <&audma1 0x48>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu04: ssiu-4 {
+                                       dmas = <&audma0 0x3F>, <&audma1 0x40>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu05: ssiu-5 {
+                                       dmas = <&audma0 0x43>, <&audma1 0x44>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu06: ssiu-6 {
+                                       dmas = <&audma0 0x4F>, <&audma1 0x50>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu07: ssiu-7 {
+                                       dmas = <&audma0 0x53>, <&audma1 0x54>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu10: ssiu-8 {
+                                       dmas = <&audma0 0x49>, <&audma1 0x4a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu11: ssiu-9 {
+                                       dmas = <&audma0 0x4B>, <&audma1 0x4C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu12: ssiu-10 {
+                                       dmas = <&audma0 0x57>, <&audma1 0x58>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu13: ssiu-11 {
+                                       dmas = <&audma0 0x59>, <&audma1 0x5A>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu14: ssiu-12 {
+                                       dmas = <&audma0 0x5F>, <&audma1 0x60>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu15: ssiu-13 {
+                                       dmas = <&audma0 0xC3>, <&audma1 0xC4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu16: ssiu-14 {
+                                       dmas = <&audma0 0xC7>, <&audma1 0xC8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu17: ssiu-15 {
+                                       dmas = <&audma0 0xCB>, <&audma1 0xCC>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu20: ssiu-16 {
+                                       dmas = <&audma0 0x63>, <&audma1 0x64>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu21: ssiu-17 {
+                                       dmas = <&audma0 0x67>, <&audma1 0x68>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu22: ssiu-18 {
+                                       dmas = <&audma0 0x6B>, <&audma1 0x6C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu23: ssiu-19 {
+                                       dmas = <&audma0 0x6D>, <&audma1 0x6E>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu24: ssiu-20 {
+                                       dmas = <&audma0 0xCF>, <&audma1 0xCE>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu25: ssiu-21 {
+                                       dmas = <&audma0 0xEB>, <&audma1 0xEC>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu26: ssiu-22 {
+                                       dmas = <&audma0 0xED>, <&audma1 0xEE>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu27: ssiu-23 {
+                                       dmas = <&audma0 0xEF>, <&audma1 0xF0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu30: ssiu-24 {
+                                       dmas = <&audma0 0x6f>, <&audma1 0x70>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu31: ssiu-25 {
+                                       dmas = <&audma0 0x21>, <&audma1 0x22>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu32: ssiu-26 {
+                                       dmas = <&audma0 0x23>, <&audma1 0x24>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu33: ssiu-27 {
+                                       dmas = <&audma0 0x25>, <&audma1 0x26>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu34: ssiu-28 {
+                                       dmas = <&audma0 0x27>, <&audma1 0x28>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu35: ssiu-29 {
+                                       dmas = <&audma0 0x29>, <&audma1 0x2A>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu36: ssiu-30 {
+                                       dmas = <&audma0 0x2B>, <&audma1 0x2C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu37: ssiu-31 {
+                                       dmas = <&audma0 0x2D>, <&audma1 0x2E>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu40: ssiu-32 {
+                                       dmas =  <&audma0 0x71>, <&audma1 0x72>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu41: ssiu-33 {
+                                       dmas = <&audma0 0x17>, <&audma1 0x18>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu42: ssiu-34 {
+                                       dmas = <&audma0 0x19>, <&audma1 0x1A>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu43: ssiu-35 {
+                                       dmas = <&audma0 0x1B>, <&audma1 0x1C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu44: ssiu-36 {
+                                       dmas = <&audma0 0x1D>, <&audma1 0x1E>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu45: ssiu-37 {
+                                       dmas = <&audma0 0x1F>, <&audma1 0x20>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu46: ssiu-38 {
+                                       dmas = <&audma0 0x31>, <&audma1 0x32>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu47: ssiu-39 {
+                                       dmas = <&audma0 0x33>, <&audma1 0x34>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu50: ssiu-40 {
+                                       dmas = <&audma0 0x73>, <&audma1 0x74>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu60: ssiu-41 {
+                                       dmas = <&audma0 0x75>, <&audma1 0x76>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu70: ssiu-42 {
+                                       dmas = <&audma0 0x79>, <&audma1 0x7a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu80: ssiu-43 {
+                                       dmas = <&audma0 0x7b>, <&audma1 0x7c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu90: ssiu-44 {
+                                       dmas = <&audma0 0x7d>, <&audma1 0x7e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu91: ssiu-45 {
+                                       dmas = <&audma0 0x7F>, <&audma1 0x80>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu92: ssiu-46 {
+                                       dmas = <&audma0 0x81>, <&audma1 0x82>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu93: ssiu-47 {
+                                       dmas = <&audma0 0x83>, <&audma1 0x84>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu94: ssiu-48 {
+                                       dmas = <&audma0 0xA3>, <&audma1 0xA4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu95: ssiu-49 {
+                                       dmas = <&audma0 0xA5>, <&audma1 0xA6>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu96: ssiu-50 {
+                                       dmas = <&audma0 0xA7>, <&audma1 0xA8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu97: ssiu-51 {
+                                       dmas = <&audma0 0xA9>, <&audma1 0xAA>;
+                                       dma-names = "rx", "tx";
+                               };
+                       };
+               };
+
+               audma0: dma-controller@ec700000 {
+                       compatible = "renesas,dmac-r8a774b1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xec700000 0 0x10000>;
+                       interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 502>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 502>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               audma1: dma-controller@ec720000 {
+                       compatible = "renesas,dmac-r8a774b1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xec720000 0 0x10000>;
+                       interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 501>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 501>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               xhci0: usb@ee000000 {
+                       compatible = "renesas,xhci-r8a774b1",
+                                    "renesas,rcar-gen3-xhci";
+                       reg = <0 0xee000000 0 0xc00>;
+                       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 328>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 328>;
+                       status = "disabled";
+               };
+
+               usb3_peri0: usb@ee020000 {
+                       compatible = "renesas,r8a774b1-usb3-peri",
+                                    "renesas,rcar-gen3-usb3-peri";
+                       reg = <0 0xee020000 0 0x400>;
+                       interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 328>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 328>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@ee080000 {
+                       compatible = "generic-ohci";
+                       reg = <0 0xee080000 0 0x100>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+                       phys = <&usb2_phy0 1>;
+                       phy-names = "usb";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 703>, <&cpg 704>;
+                       status = "disabled";
+               };
+
+               ohci1: usb@ee0a0000 {
+                       compatible = "generic-ohci";
+                       reg = <0 0xee0a0000 0 0x100>;
+                       interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 702>;
+                       phys = <&usb2_phy1 1>;
+                       phy-names = "usb";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 702>;
+                       status = "disabled";
+               };
+
+               ehci0: usb@ee080100 {
+                       compatible = "generic-ehci";
+                       reg = <0 0xee080100 0 0x100>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+                       phys = <&usb2_phy0 2>;
+                       phy-names = "usb";
+                       companion = <&ohci0>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 703>, <&cpg 704>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@ee0a0100 {
+                       compatible = "generic-ehci";
+                       reg = <0 0xee0a0100 0 0x100>;
+                       interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 702>;
+                       phys = <&usb2_phy1 2>;
+                       phy-names = "usb";
+                       companion = <&ohci1>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 702>;
+                       status = "disabled";
+               };
+
+               usb2_phy0: usb-phy@ee080200 {
+                       compatible = "renesas,usb2-phy-r8a774b1",
+                                    "renesas,rcar-gen3-usb2-phy";
+                       reg = <0 0xee080200 0 0x700>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 703>, <&cpg 704>;
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
+
+               usb2_phy1: usb-phy@ee0a0200 {
+                       compatible = "renesas,usb2-phy-r8a774b1",
+                                    "renesas,rcar-gen3-usb2-phy";
+                       reg = <0 0xee0a0200 0 0x700>;
+                       clocks = <&cpg CPG_MOD 702>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 702>;
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
+
+               sdhi0: sd@ee100000 {
+                       compatible = "renesas,sdhi-r8a774b1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee100000 0 0x2000>;
+                       interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 314>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 314>;
+                       status = "disabled";
+               };
+
+               sdhi1: sd@ee120000 {
+                       compatible = "renesas,sdhi-r8a774b1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee120000 0 0x2000>;
+                       interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 313>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 313>;
+                       status = "disabled";
+               };
+
+               sdhi2: sd@ee140000 {
+                       compatible = "renesas,sdhi-r8a774b1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee140000 0 0x2000>;
+                       interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 312>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 312>;
+                       status = "disabled";
+               };
+
+               sdhi3: sd@ee160000 {
+                       compatible = "renesas,sdhi-r8a774b1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee160000 0 0x2000>;
+                       interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 311>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 311>;
+                       status = "disabled";
+               };
+
+               sata: sata@ee300000 {
+                       compatible = "renesas,sata-r8a774b1",
+                                    "renesas,rcar-gen3-sata";
+                       reg = <0 0xee300000 0 0x200000>;
+                       interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 815>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 815>;
+                       status = "disabled";
+               };
+
+               gic: interrupt-controller@f1010000 {
+                       compatible = "arm,gic-400";
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+                       interrupt-controller;
+                       reg = <0x0 0xf1010000 0 0x1000>,
+                             <0x0 0xf1020000 0 0x20000>,
+                             <0x0 0xf1040000 0 0x20000>,
+                             <0x0 0xf1060000 0 0x20000>;
+                       interrupts = <GIC_PPI 9
+                                       (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+                       clocks = <&cpg CPG_MOD 408>;
+                       clock-names = "clk";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 408>;
+               };
+
+               pciec0: pcie@fe000000 {
+                       compatible = "renesas,pcie-r8a774b1",
+                                    "renesas,pcie-rcar-gen3";
+                       reg = <0 0xfe000000 0 0x80000>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       bus-range = <0x00 0xff>;
+                       device_type = "pci";
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+                                 0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+                                 0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+                                 0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+                       /* Map all possible DDR as inbound ranges */
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+                       interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+                       clock-names = "pcie", "pcie_bus";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 319>;
+                       status = "disabled";
+               };
+
+               pciec1: pcie@ee800000 {
+                       compatible = "renesas,pcie-r8a774b1",
+                                    "renesas,pcie-rcar-gen3";
+                       reg = <0 0xee800000 0 0x80000>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       bus-range = <0x00 0xff>;
+                       device_type = "pci";
+                       ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000
+                                 0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000
+                                 0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000
+                                 0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>;
+                       /* Map all possible DDR as inbound ranges */
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>;
+                       clock-names = "pcie", "pcie_bus";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 318>;
+                       status = "disabled";
+               };
+
+               fdp1@fe940000 {
+                       compatible = "renesas,fdp1";
+                       reg = <0 0xfe940000 0 0x2400>;
+                       interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 119>;
+                       power-domains = <&sysc R8A774B1_PD_A3VP>;
+                       resets = <&cpg 119>;
+                       renesas,fcp = <&fcpf0>;
+               };
+
+               fcpf0: fcp@fe950000 {
+                       compatible = "renesas,fcpf";
+                       reg = <0 0xfe950000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 615>;
+                       power-domains = <&sysc R8A774B1_PD_A3VP>;
+                       resets = <&cpg 615>;
+               };
+
+               vspb: vsp@fe960000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfe960000 0 0x8000>;
+                       interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 626>;
+                       power-domains = <&sysc R8A774B1_PD_A3VP>;
+                       resets = <&cpg 626>;
+
+                       renesas,fcp = <&fcpvb0>;
+               };
+
+               vspi0: vsp@fe9a0000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfe9a0000 0 0x8000>;
+                       interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 631>;
+                       power-domains = <&sysc R8A774B1_PD_A3VP>;
+                       resets = <&cpg 631>;
+
+                       renesas,fcp = <&fcpvi0>;
+               };
+
+               vspd0: vsp@fea20000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea20000 0 0x5000>;
+                       interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 623>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 623>;
+
+                       renesas,fcp = <&fcpvd0>;
+               };
+
+               vspd1: vsp@fea28000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea28000 0 0x5000>;
+                       interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 622>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 622>;
+
+                       renesas,fcp = <&fcpvd1>;
+               };
+
+               fcpvb0: fcp@fe96f000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe96f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 607>;
+                       power-domains = <&sysc R8A774B1_PD_A3VP>;
+                       resets = <&cpg 607>;
+               };
+
+               fcpvd0: fcp@fea27000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea27000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 603>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 603>;
+               };
+
+               fcpvd1: fcp@fea2f000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea2f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 602>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 602>;
+               };
+
+               fcpvi0: fcp@fe9af000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe9af000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 611>;
+                       power-domains = <&sysc R8A774B1_PD_A3VP>;
+                       resets = <&cpg 611>;
+               };
+
+               csi20: csi2@fea80000 {
+                       compatible = "renesas,r8a774b1-csi2";
+                       reg = <0 0xfea80000 0 0x10000>;
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 714>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 714>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       csi20vin0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&vin0csi20>;
+                                       };
+                                       csi20vin1: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&vin1csi20>;
+                                       };
+                                       csi20vin2: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&vin2csi20>;
+                                       };
+                                       csi20vin3: endpoint@3 {
+                                               reg = <3>;
+                                               remote-endpoint = <&vin3csi20>;
+                                       };
+                                       csi20vin4: endpoint@4 {
+                                               reg = <4>;
+                                               remote-endpoint = <&vin4csi20>;
+                                       };
+                                       csi20vin5: endpoint@5 {
+                                               reg = <5>;
+                                               remote-endpoint = <&vin5csi20>;
+                                       };
+                                       csi20vin6: endpoint@6 {
+                                               reg = <6>;
+                                               remote-endpoint = <&vin6csi20>;
+                                       };
+                                       csi20vin7: endpoint@7 {
+                                               reg = <7>;
+                                               remote-endpoint = <&vin7csi20>;
+                                       };
+                               };
+                       };
+               };
+
+               csi40: csi2@feaa0000 {
+                       compatible = "renesas,r8a774b1-csi2";
+                       reg = <0 0xfeaa0000 0 0x10000>;
+                       interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 716>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 716>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       csi40vin0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&vin0csi40>;
+                                       };
+                                       csi40vin1: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&vin1csi40>;
+                                       };
+                                       csi40vin2: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&vin2csi40>;
+                                       };
+                                       csi40vin3: endpoint@3 {
+                                               reg = <3>;
+                                               remote-endpoint = <&vin3csi40>;
+                                       };
+                                       csi40vin4: endpoint@4 {
+                                               reg = <4>;
+                                               remote-endpoint = <&vin4csi40>;
+                                       };
+                                       csi40vin5: endpoint@5 {
+                                               reg = <5>;
+                                               remote-endpoint = <&vin5csi40>;
+                                       };
+                                       csi40vin6: endpoint@6 {
+                                               reg = <6>;
+                                               remote-endpoint = <&vin6csi40>;
+                                       };
+                                       csi40vin7: endpoint@7 {
+                                               reg = <7>;
+                                               remote-endpoint = <&vin7csi40>;
+                                       };
+                               };
+                       };
+               };
+
+               hdmi0: hdmi@fead0000 {
+                       compatible = "renesas,r8a774b1-hdmi",
+                                    "renesas,rcar-gen3-hdmi";
+                       reg = <0 0xfead0000 0 0x10000>;
+                       interrupts = <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 729>,
+                                <&cpg CPG_CORE R8A774B1_CLK_HDMI>;
+                       clock-names = "iahb", "isfr";
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 729>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       dw_hdmi0_in: endpoint {
+                                               remote-endpoint = <&du_out_hdmi0>;
+                                       };
+                               };
+                               port@1 {
+                                       reg = <1>;
+                               };
+                               port@2 {
+                                       /* HDMI sound */
+                                       reg = <2>;
+                               };
+                       };
+               };
+
+               du: display@feb00000 {
+                       compatible = "renesas,du-r8a774b1";
+                       reg = <0 0xfeb00000 0 0x80000>;
+                       interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 724>,
+                                <&cpg CPG_MOD 723>,
+                                <&cpg CPG_MOD 721>;
+                       clock-names = "du.0", "du.1", "du.3";
+                       status = "disabled";
+
+                       vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       du_out_rgb: endpoint {
+                                       };
+                               };
+                               port@1 {
+                                       reg = <1>;
+                                       du_out_hdmi0: endpoint {
+                                               remote-endpoint = <&dw_hdmi0_in>;
+                                       };
+                               };
+                               port@2 {
+                                       reg = <2>;
+                                       du_out_lvds0: endpoint {
+                                               remote-endpoint = <&lvds0_in>;
+                                       };
+                               };
+                       };
+               };
+
+               lvds0: lvds@feb90000 {
+                       compatible = "renesas,r8a774b1-lvds";
+                       reg = <0 0xfeb90000 0 0x14>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
+                       resets = <&cpg 727>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds0_in: endpoint {
+                                               remote-endpoint = <&du_out_lvds0>;
+                                       };
+                               };
+                               port@1 {
+                                       reg = <1>;
+                                       lvds0_out: endpoint {
+                                       };
+                               };
+                       };
+               };
+
+               prr: chipid@fff00044 {
+                       compatible = "renesas,prr";
+                       reg = <0 0xfff00044 0 4>;
+               };
+       };
+
+       thermal-zones {
+               sensor_thermal1: sensor-thermal1 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 0>;
+                       sustainable-power = <2439>;
+
+                       trips {
+                               sensor1_crit: sensor1-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               sensor_thermal2: sensor-thermal2 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 1>;
+                       sustainable-power = <2439>;
+
+                       trips {
+                               sensor2_crit: sensor2-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               sensor_thermal3: sensor-thermal3 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 2>;
+                       sustainable-power = <2439>;
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&target>;
+                                       cooling-device = <&a57_0 0 2>;
+                                       contribution = <1024>;
+                               };
+                       };
+                       trips {
+                               target: trip-point1 {
+                                       temperature = <100000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+
+                               sensor3_crit: sensor3-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       /* External USB clocks - can be overridden by the board */
+       usb3s0_clk: usb3s0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       usb_extal_clk: usb_extal {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+};
index a1c2de9..c7bdc36 100644 (file)
                        compatible = "arm,cortex-a53";
                        reg = <0>;
                        device_type = "cpu";
+                       #cooling-cells = <2>;
                        power-domains = <&sysc R8A774C0_PD_CA53_CPU0>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       dynamic-power-coefficient = <277>;
                        clocks = <&cpg CPG_CORE R8A774C0_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
        thermal-zones {
                cpu-thermal {
                        polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-                       thermal-sensors = <&thermal>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&thermal 0>;
+                       sustainable-power = <717>;
 
                        cooling-maps {
+                               map0 {
+                                       trip = <&target>;
+                                       cooling-device = <&a53_0 0 2>;
+                                       contribution = <1024>;
+                               };
                        };
 
                        trips {
-                               cpu-crit {
+                               sensor1_crit: sensor1-crit {
                                        temperature = <120000>;
                                        hysteresis = <2000>;
                                        type = "critical";
                                };
+
+                               target: trip-point1 {
+                                       temperature = <100000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
                        };
                };
        };
index e4650ae..14d8513 100644 (file)
@@ -30,7 +30,7 @@
 };
 
 &du {
-       vsps = <&vspd0 &vspd1 &vspd2 &vspd3>;
+       vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd3 0>;
 };
 
 &fcpvb1 {
index 95deff6..fde6ec1 100644 (file)
                        power-domains = <&sysc R8A7795_PD_CA57_CPU0>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                        dynamic-power-coefficient = <854>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        power-domains = <&sysc R8A7795_PD_CA57_CPU1>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        capacity-dmips-mhz = <1024>;
                        power-domains = <&sysc R8A7795_PD_CA57_CPU2>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        capacity-dmips-mhz = <1024>;
                        power-domains = <&sysc R8A7795_PD_CA57_CPU3>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        capacity-dmips-mhz = <1024>;
                        power-domains = <&sysc R8A7795_PD_CA53_CPU0>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        #cooling-cells = <2>;
                        dynamic-power-coefficient = <277>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        power-domains = <&sysc R8A7795_PD_CA53_CPU1>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                        capacity-dmips-mhz = <535>;
                        power-domains = <&sysc R8A7795_PD_CA53_CPU2>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                        capacity-dmips-mhz = <535>;
                        power-domains = <&sysc R8A7795_PD_CA53_CPU3>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                        capacity-dmips-mhz = <535>;
                        cache-unified;
                        cache-level = <2>;
                };
+
+               idle-states {
+                       entry-method = "psci";
+
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <400>;
+                               exit-latency-us = <500>;
+                               min-residency-us = <4000>;
+                       };
+
+                       CPU_SLEEP_1: cpu-sleep-1 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <700>;
+                               exit-latency-us = <700>;
+                               min-residency-us = <5000>;
+                       };
+               };
        };
 
        extal_clk: extal {
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        resets = <&cpg 314>;
+                       iommus = <&ipmmu_ds1 32>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        resets = <&cpg 313>;
+                       iommus = <&ipmmu_ds1 33>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        resets = <&cpg 312>;
+                       iommus = <&ipmmu_ds1 34>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        resets = <&cpg 311>;
+                       iommus = <&ipmmu_ds1 35>;
                        status = "disabled";
                };
 
                        iommus = <&ipmmu_vi1 10>;
                };
 
+               cmm0: cmm@fea40000 {
+                       compatible = "renesas,r8a7795-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea40000 0 0x1000>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 711>;
+                       resets = <&cpg 711>;
+               };
+
+               cmm1: cmm@fea50000 {
+                       compatible = "renesas,r8a7795-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea50000 0 0x1000>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 710>;
+                       resets = <&cpg 710>;
+               };
+
+               cmm2: cmm@fea60000 {
+                       compatible = "renesas,r8a7795-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea60000 0 0x1000>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 709>;
+                       resets = <&cpg 709>;
+               };
+
+               cmm3: cmm@fea70000 {
+                       compatible = "renesas,r8a7795-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea70000 0 0x1000>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 708>;
+                       resets = <&cpg 708>;
+               };
+
                csi20: csi2@fea80000 {
                        compatible = "renesas,r8a7795-csi2";
                        reg = <0 0xfea80000 0 0x10000>;
                                 <&cpg CPG_MOD 722>,
                                 <&cpg CPG_MOD 721>;
                        clock-names = "du.0", "du.1", "du.2", "du.3";
+
+                       renesas,cmms = <&cmm0>, <&cmm1>, <&cmm2>, <&cmm3>;
                        vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>;
+
                        status = "disabled";
 
                        ports {
index 3dc9d73..b9db882 100644 (file)
                        power-domains = <&sysc R8A7796_PD_CA57_CPU0>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                        dynamic-power-coefficient = <854>;
                        clocks = <&cpg CPG_CORE R8A7796_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        power-domains = <&sysc R8A7796_PD_CA57_CPU1>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&cpg CPG_CORE R8A7796_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        capacity-dmips-mhz = <1024>;
                        power-domains = <&sysc R8A7796_PD_CA53_CPU0>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        #cooling-cells = <2>;
                        dynamic-power-coefficient = <277>;
                        clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        power-domains = <&sysc R8A7796_PD_CA53_CPU1>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                        capacity-dmips-mhz = <535>;
                        power-domains = <&sysc R8A7796_PD_CA53_CPU2>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                        capacity-dmips-mhz = <535>;
                        power-domains = <&sysc R8A7796_PD_CA53_CPU3>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
                        clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                        capacity-dmips-mhz = <535>;
                        cache-unified;
                        cache-level = <2>;
                };
+
+               idle-states {
+                       entry-method = "psci";
+
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <400>;
+                               exit-latency-us = <500>;
+                               min-residency-us = <4000>;
+                       };
+
+                       CPU_SLEEP_1: cpu-sleep-1 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <700>;
+                               exit-latency-us = <700>;
+                               min-residency-us = <5000>;
+                       };
+               };
        };
 
        extal_clk: extal {
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
                        resets = <&cpg 314>;
+                       iommus = <&ipmmu_ds1 32>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
                        resets = <&cpg 313>;
+                       iommus = <&ipmmu_ds1 33>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
                        resets = <&cpg 312>;
+                       iommus = <&ipmmu_ds1 34>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
                        resets = <&cpg 311>;
+                       iommus = <&ipmmu_ds1 35>;
                        status = "disabled";
                };
 
                        renesas,fcp = <&fcpvi0>;
                };
 
+               cmm0: cmm@fea40000 {
+                       compatible = "renesas,r8a7796-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea40000 0 0x1000>;
+                       power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 711>;
+                       resets = <&cpg 711>;
+               };
+
+               cmm1: cmm@fea50000 {
+                       compatible = "renesas,r8a7796-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea50000 0 0x1000>;
+                       power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 710>;
+                       resets = <&cpg 710>;
+               };
+
+               cmm2: cmm@fea60000 {
+                       compatible = "renesas,r8a7796-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea60000 0 0x1000>;
+                       power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 709>;
+                       resets = <&cpg 709>;
+               };
+
                csi20: csi2@fea80000 {
                        compatible = "renesas,r8a7796-csi2";
                        reg = <0 0xfea80000 0 0x10000>;
                                 <&cpg CPG_MOD 723>,
                                 <&cpg CPG_MOD 722>;
                        clock-names = "du.0", "du.1", "du.2";
-                       status = "disabled";
 
-                       vsps = <&vspd0 &vspd1 &vspd2>;
+                       renesas,cmms = <&cmm0>, <&cmm1>, <&cmm2>;
+                       vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>;
+
+                       status = "disabled";
 
                        ports {
                                #address-cells = <1>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts
new file mode 100644 (file)
index 0000000..4abd78a
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car M3-W+
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a77961.dtsi"
+#include "salvator-xs.dtsi"
+
+/ {
+       model = "Renesas Salvator-X 2nd version board based on r8a77961";
+       compatible = "renesas,salvator-xs", "renesas,r8a77961";
+
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0x0 0x48000000 0x0 0x78000000>;
+       };
+
+       memory@400000000 {
+               device_type = "memory";
+               reg = <0x4 0x80000000 0x0 0x80000000>;
+       };
+
+       memory@600000000 {
+               device_type = "memory";
+               reg = <0x6 0x00000000 0x1 0x00000000>;
+       };
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
new file mode 100644 (file)
index 0000000..64466c8
--- /dev/null
@@ -0,0 +1,723 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the R-Car M3-W+ (R8A77961) SoC
+ *
+ * Copyright (C) 2016-2017 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/r8a77961-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/r8a77961-sysc.h>
+
+#define CPG_AUDIO_CLK_I                R8A77961_CLK_S0D4
+
+/ {
+       compatible = "renesas,r8a77961";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       /*
+        * The external audio clocks are configured as 0 Hz fixed frequency
+        * clocks by default.
+        * Boards that provide audio clocks should override them.
+        */
+       audio_clk_a: audio_clk_a {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_b: audio_clk_b {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_c: audio_clk_c {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       /* External CAN clock - to be overridden by boards that provide it */
+       can_clk: can {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       cluster0_opp: opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <820000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <820000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1500000000 {
+                       opp-hz = /bits/ 64 <1500000000>;
+                       opp-microvolt = <820000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1600000000 {
+                       opp-hz = /bits/ 64 <1600000000>;
+                       opp-microvolt = <900000>;
+                       clock-latency-ns = <300000>;
+                       turbo-mode;
+               };
+               opp-1700000000 {
+                       opp-hz = /bits/ 64 <1700000000>;
+                       opp-microvolt = <900000>;
+                       clock-latency-ns = <300000>;
+                       turbo-mode;
+               };
+               opp-1800000000 {
+                       opp-hz = /bits/ 64 <1800000000>;
+                       opp-microvolt = <960000>;
+                       clock-latency-ns = <300000>;
+                       turbo-mode;
+               };
+       };
+
+       cluster1_opp: opp_table1 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-800000000 {
+                       opp-hz = /bits/ 64 <800000000>;
+                       opp-microvolt = <820000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <820000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <820000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1300000000 {
+                       opp-hz = /bits/ 64 <1300000000>;
+                       opp-microvolt = <820000>;
+                       clock-latency-ns = <300000>;
+                       turbo-mode;
+               };
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #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";
+                       reg = <0x0>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A77961_PD_CA57_CPU0>;
+                       next-level-cache = <&L2_CA57>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
+                       dynamic-power-coefficient = <854>;
+                       clocks = <&cpg CPG_CORE R8A77961_CLK_Z>;
+                       operating-points-v2 = <&cluster0_opp>;
+                       capacity-dmips-mhz = <1024>;
+                       #cooling-cells = <2>;
+               };
+
+               a57_1: cpu@1 {
+                       compatible = "arm,cortex-a57";
+                       reg = <0x1>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A77961_PD_CA57_CPU1>;
+                       next-level-cache = <&L2_CA57>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
+                       clocks = <&cpg CPG_CORE R8A77961_CLK_Z>;
+                       operating-points-v2 = <&cluster0_opp>;
+                       capacity-dmips-mhz = <1024>;
+                       #cooling-cells = <2>;
+               };
+
+               a53_0: cpu@100 {
+                       compatible = "arm,cortex-a53";
+                       reg = <0x100>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A77961_PD_CA53_CPU0>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
+                       #cooling-cells = <2>;
+                       dynamic-power-coefficient = <277>;
+                       clocks = <&cpg CPG_CORE R8A77961_CLK_Z2>;
+                       operating-points-v2 = <&cluster1_opp>;
+                       capacity-dmips-mhz = <535>;
+               };
+
+               a53_1: cpu@101 {
+                       compatible = "arm,cortex-a53";
+                       reg = <0x101>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A77961_PD_CA53_CPU1>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
+                       clocks = <&cpg CPG_CORE R8A77961_CLK_Z2>;
+                       operating-points-v2 = <&cluster1_opp>;
+                       capacity-dmips-mhz = <535>;
+               };
+
+               a53_2: cpu@102 {
+                       compatible = "arm,cortex-a53";
+                       reg = <0x102>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A77961_PD_CA53_CPU2>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
+                       clocks = <&cpg CPG_CORE R8A77961_CLK_Z2>;
+                       operating-points-v2 = <&cluster1_opp>;
+                       capacity-dmips-mhz = <535>;
+               };
+
+               a53_3: cpu@103 {
+                       compatible = "arm,cortex-a53";
+                       reg = <0x103>;
+                       device_type = "cpu";
+                       power-domains = <&sysc R8A77961_PD_CA53_CPU3>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_1>;
+                       clocks = <&cpg CPG_CORE R8A77961_CLK_Z2>;
+                       operating-points-v2 = <&cluster1_opp>;
+                       capacity-dmips-mhz = <535>;
+               };
+
+               L2_CA57: cache-controller-0 {
+                       compatible = "cache";
+                       power-domains = <&sysc R8A77961_PD_CA57_SCU>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               L2_CA53: cache-controller-1 {
+                       compatible = "cache";
+                       power-domains = <&sysc R8A77961_PD_CA53_SCU>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               idle-states {
+                       entry-method = "psci";
+
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <400>;
+                               exit-latency-us = <500>;
+                               min-residency-us = <4000>;
+                       };
+
+                       CPU_SLEEP_1: cpu-sleep-1 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <700>;
+                               exit-latency-us = <700>;
+                               min-residency-us = <5000>;
+                       };
+               };
+       };
+
+       extal_clk: extal {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       extalr_clk: extalr {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       /* External PCIe clock - can be overridden by the board */
+       pcie_bus_clk: pcie_bus {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       pmu_a53 {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>;
+       };
+
+       pmu_a57 {
+               compatible = "arm,cortex-a57-pmu";
+               interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&a57_0>, <&a57_1>;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0", "arm,psci-0.2";
+               method = "smc";
+       };
+
+       /* External SCIF clock - to be overridden by boards that provide it */
+       scif_clk: scif {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               interrupt-parent = <&gic>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               rwdt: watchdog@e6020000 {
+                       reg = <0 0xe6020000 0 0x0c>;
+                       /* placeholder */
+               };
+
+               gpio2: gpio@e6052000 {
+                       reg = <0 0xe6052000 0 0x50>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       /* placeholder */
+               };
+
+               gpio3: gpio@e6053000 {
+                       reg = <0 0xe6053000 0 0x50>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       /* placeholder */
+               };
+
+               gpio4: gpio@e6054000 {
+                       reg = <0 0xe6054000 0 0x50>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       /* placeholder */
+               };
+
+               gpio5: gpio@e6055000 {
+                       reg = <0 0xe6055000 0 0x50>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       /* placeholder */
+               };
+
+               gpio6: gpio@e6055400 {
+                       reg = <0 0xe6055400 0 0x50>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       /* placeholder */
+               };
+
+               pfc: pin-controller@e6060000 {
+                       compatible = "renesas,pfc-r8a77961";
+                       reg = <0 0xe6060000 0 0x50c>;
+               };
+
+               cpg: clock-controller@e6150000 {
+                       compatible = "renesas,r8a77961-cpg-mssr";
+                       reg = <0 0xe6150000 0 0x1000>;
+                       clocks = <&extal_clk>, <&extalr_clk>;
+                       clock-names = "extal", "extalr";
+                       #clock-cells = <2>;
+                       #power-domain-cells = <0>;
+                       #reset-cells = <1>;
+               };
+
+               rst: reset-controller@e6160000 {
+                       compatible = "renesas,r8a77961-rst";
+                       reg = <0 0xe6160000 0 0x0200>;
+               };
+
+               sysc: system-controller@e6180000 {
+                       compatible = "renesas,r8a77961-sysc";
+                       reg = <0 0xe6180000 0 0x0400>;
+                       #power-domain-cells = <1>;
+               };
+
+               intc_ex: interrupt-controller@e61c0000 {
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <0 0xe61c0000 0 0x200>;
+                       /* placeholder */
+               };
+
+               i2c2: i2c@e6510000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0 0xe6510000 0 0x40>;
+                       /* placeholder */
+               };
+
+               i2c4: i2c@e66d8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0 0xe66d8000 0 0x40>;
+                       /* placeholder */
+               };
+
+               i2c_dvfs: i2c@e60b0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0 0xe60b0000 0 0x425>;
+                       /* placeholder */
+               };
+
+               hscif1: serial@e6550000 {
+                       reg = <0 0xe6550000 0 0x60>;
+                       /* placeholder */
+               };
+
+               hsusb: usb@e6590000 {
+                       reg = <0 0xe6590000 0 0x200>;
+                       /* placeholder */
+               };
+
+               usb3_phy0: usb-phy@e65ee000 {
+                       reg = <0 0xe65ee000 0 0x90>;
+                       #phy-cells = <0>;
+                       /* placeholder */
+               };
+
+               avb: ethernet@e6800000 {
+                       reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       /* placeholder */
+               };
+
+               pwm1: pwm@e6e31000 {
+                       reg = <0 0xe6e31000 0 8>;
+                       #pwm-cells = <2>;
+                       /* placeholder */
+               };
+
+               scif1: serial@e6e68000 {
+                       reg = <0 0xe6e68000 0 64>;
+                       /* placeholder */
+               };
+
+               scif2: serial@e6e88000 {
+                       compatible = "renesas,scif-r8a77961",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e88000 0 64>;
+                       interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 310>,
+                                <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 310>;
+                       status = "disabled";
+               };
+
+               vin0: video@e6ef0000 {
+                       reg = <0 0xe6ef0000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               vin1: video@e6ef1000 {
+                       reg = <0 0xe6ef1000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               vin2: video@e6ef2000 {
+                       reg = <0 0xe6ef2000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               vin3: video@e6ef3000 {
+                       reg = <0 0xe6ef3000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               vin4: video@e6ef4000 {
+                       reg = <0 0xe6ef4000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               vin5: video@e6ef5000 {
+                       reg = <0 0xe6ef5000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               vin6: video@e6ef6000 {
+                       reg = <0 0xe6ef6000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               vin7: video@e6ef7000 {
+                       reg = <0 0xe6ef7000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               rcar_sound: sound@ec500000 {
+                       reg = <0 0xec500000 0 0x1000>, /* SCU */
+                             <0 0xec5a0000 0 0x100>,  /* ADG */
+                             <0 0xec540000 0 0x1000>, /* SSIU */
+                             <0 0xec541000 0 0x280>,  /* SSI */
+                             <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+                       /* placeholder */
+                       rcar_sound,dvc {
+                               dvc0: dvc-0 { };
+                               dvc1: dvc-1 { };
+                       };
+
+                       rcar_sound,src {
+                               src0: src-0 { };
+                               src1: src-1 { };
+                       };
+
+                       rcar_sound,ssi {
+                               ssi0: ssi-0 { };
+                               ssi1: ssi-1 { };
+                       };
+               };
+
+               xhci0: usb@ee000000 {
+                       reg = <0 0xee000000 0 0xc00>;
+                       /* placeholder */
+               };
+
+               usb3_peri0: usb@ee020000 {
+                       reg = <0 0xee020000 0 0x400>;
+                       /* placeholder */
+               };
+
+               ohci0: usb@ee080000 {
+                       reg = <0 0xee080000 0 0x100>;
+                       /* placeholder */
+               };
+
+               ohci1: usb@ee0a0000 {
+                       reg = <0 0xee0a0000 0 0x100>;
+                       /* placeholder */
+               };
+
+               ehci0: usb@ee080100 {
+                       reg = <0 0xee080100 0 0x100>;
+                       /* placeholder */
+               };
+
+               ehci1: usb@ee0a0100 {
+                       reg = <0 0xee0a0100 0 0x100>;
+                       /* placeholder */
+               };
+
+               usb2_phy0: usb-phy@ee080200 {
+                       reg = <0 0xee080200 0 0x700>;
+                       /* placeholder */
+               };
+
+               usb2_phy1: usb-phy@ee0a0200 {
+                       reg = <0 0xee0a0200 0 0x700>;
+                       /* placeholder */
+               };
+
+               sdhi0: sd@ee100000 {
+                       reg = <0 0xee100000 0 0x2000>;
+                       /* placeholder */
+               };
+
+               sdhi2: sd@ee140000 {
+                       reg = <0 0xee140000 0 0x2000>;
+                       /* placeholder */
+               };
+
+               sdhi3: sd@ee160000 {
+                       reg = <0 0xee160000 0 0x2000>;
+                       /* placeholder */
+               };
+
+               gic: interrupt-controller@f1010000 {
+                       compatible = "arm,gic-400";
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+                       interrupt-controller;
+                       reg = <0x0 0xf1010000 0 0x1000>,
+                             <0x0 0xf1020000 0 0x20000>,
+                             <0x0 0xf1040000 0 0x20000>,
+                             <0x0 0xf1060000 0 0x20000>;
+                       interrupts = <GIC_PPI 9
+                                       (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+                       clocks = <&cpg CPG_MOD 408>;
+                       clock-names = "clk";
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 408>;
+               };
+
+               pciec0: pcie@fe000000 {
+                       reg = <0 0xfe000000 0 0x80000>;
+                       /* placeholder */
+               };
+
+               pciec1: pcie@ee800000 {
+                       reg = <0 0xee800000 0 0x80000>;
+                       /* placeholder */
+               };
+
+               csi20: csi2@fea80000 {
+                       reg = <0 0xfea80000 0 0x10000>;
+                       /* placeholder */
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               csi40: csi2@feaa0000 {
+                       reg = <0 0xfeaa0000 0 0x10000>;
+                       /* placeholder */
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               hdmi0: hdmi@fead0000 {
+                       reg = <0 0xfead0000 0 0x10000>;
+                       /* placeholder */
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               port@0 {
+                                       reg = <0>;
+                               };
+                               port@1 {
+                                       reg = <1>;
+                               };
+                               port@2 {
+                                       /* HDMI sound */
+                                       reg = <2>;
+                               };
+                       };
+               };
+
+               du: display@feb00000 {
+                       reg = <0 0xfeb00000 0 0x70000>;
+                       /* placeholder */
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       du_out_rgb: endpoint {
+                                       };
+                               };
+                               port@1 {
+                                       reg = <1>;
+                                       du_out_hdmi0: endpoint {
+                                       };
+                               };
+                               port@2 {
+                                       reg = <2>;
+                                       du_out_lvds0: endpoint {
+                                       };
+                               };
+                       };
+               };
+
+               prr: chipid@fff00044 {
+                       compatible = "renesas,prr";
+                       reg = <0 0xfff00044 0 4>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       /* External USB clocks - can be overridden by the board */
+       usb3s0_clk: usb3s0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       usb_extal_clk: usb_extal {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+};
index 4ae1632..bdbe197 100644 (file)
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
                        resets = <&cpg 314>;
+                       iommus = <&ipmmu_ds1 32>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
                        resets = <&cpg 313>;
+                       iommus = <&ipmmu_ds1 33>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
                        resets = <&cpg 312>;
+                       iommus = <&ipmmu_ds1 34>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
                        resets = <&cpg 311>;
+                       iommus = <&ipmmu_ds1 35>;
                        status = "disabled";
                };
 
                        resets = <&cpg 611>;
                };
 
+               cmm0: cmm@fea40000 {
+                       compatible = "renesas,r8a77965-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea40000 0 0x1000>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 711>;
+                       resets = <&cpg 711>;
+               };
+
+               cmm1: cmm@fea50000 {
+                       compatible = "renesas,r8a77965-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea50000 0 0x1000>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 710>;
+                       resets = <&cpg 710>;
+               };
+
+               cmm3: cmm@fea70000 {
+                       compatible = "renesas,r8a77965-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea70000 0 0x1000>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 708>;
+                       resets = <&cpg 708>;
+               };
+
                csi20: csi2@fea80000 {
                        compatible = "renesas,r8a77965-csi2";
                        reg = <0 0xfea80000 0 0x10000>;
                                 <&cpg CPG_MOD 723>,
                                 <&cpg CPG_MOD 721>;
                        clock-names = "du.0", "du.1", "du.3";
-                       status = "disabled";
 
+                       renesas,cmms = <&cmm0>, <&cmm1>, <&cmm3>;
                        vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>;
 
+                       status = "disabled";
+
                        ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
index 0cd3b37..0d0558e 100644 (file)
                };
 
                pwm3: pwm@e6e33000 {
-                       compatible = "renesas,pwm-r8a7790", "renesas,pwm-rcar";
+                       compatible = "renesas,pwm-r8a77970", "renesas,pwm-rcar";
                        reg = <0 0xe6e33000 0 8>;
                        #pwm-cells = <2>;
                        clocks = <&cpg CPG_MOD 523>;
                        power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
                        resets = <&cpg 314>;
                        max-frequency = <200000000>;
+                       iommus = <&ipmmu_ds1 32>;
                        status = "disabled";
                };
 
                        clock-names = "du.0";
                        power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
                        resets = <&cpg 724>;
-                       vsps = <&vspd0>;
+                       vsps = <&vspd0 0>;
                        status = "disabled";
 
                        ports {
index 461a47e..4d86669 100644 (file)
                        power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
                        resets = <&cpg 314>;
                        max-frequency = <200000000>;
+                       iommus = <&ipmmu_ds1 32>;
                        status = "disabled";
                };
 
                        clock-names = "du.0";
                        power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
                        resets = <&cpg 724>;
-                       vsps = <&vspd0>;
+                       vsps = <&vspd0 0>;
                        status = "disabled";
 
                        ports {
index 455954c..67a6824 100644 (file)
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 314>;
+                       iommus = <&ipmmu_ds1 32>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 313>;
+                       iommus = <&ipmmu_ds1 33>;
                        status = "disabled";
                };
 
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 311>;
+                       iommus = <&ipmmu_ds1 35>;
                        status = "disabled";
                };
 
                        iommus = <&ipmmu_vi0 9>;
                };
 
+               cmm0: cmm@fea40000 {
+                       compatible = "renesas,r8a77990-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea40000 0 0x1000>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 711>;
+                       resets = <&cpg 711>;
+               };
+
+               cmm1: cmm@fea50000 {
+                       compatible = "renesas,r8a77990-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea50000 0 0x1000>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 710>;
+                       resets = <&cpg 710>;
+               };
+
                csi40: csi2@feaa0000 {
                        compatible = "renesas,r8a77990-csi2";
                        reg = <0 0xfeaa0000 0 0x10000>;
                        clock-names = "du.0", "du.1";
                        resets = <&cpg 724>;
                        reset-names = "du.0";
+
+                       renesas,cmms = <&cmm0>, <&cmm1>;
                        vsps = <&vspd0 0>, <&vspd1 0>;
+
                        status = "disabled";
 
                        ports {
index 183fef8..e6ee2b7 100644 (file)
                        max-frequency = <200000000>;
                        power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        resets = <&cpg 312>;
+                       iommus = <&ipmmu_ds1 34>;
                        status = "disabled";
                };
 
                        iommus = <&ipmmu_vi0 9>;
                };
 
+               cmm0: cmm@fea40000 {
+                       compatible = "renesas,r8a77995-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea40000 0 0x1000>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 711>;
+                       resets = <&cpg 711>;
+               };
+
+               cmm1: cmm@fea50000 {
+                       compatible = "renesas,r8a77995-cmm",
+                                    "renesas,rcar-gen3-cmm";
+                       reg = <0 0xfea50000 0 0x1000>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       clocks = <&cpg CPG_MOD 710>;
+                       resets = <&cpg 710>;
+               };
+
                du: display@feb00000 {
                        compatible = "renesas,du-r8a77995";
                        reg = <0 0xfeb00000 0 0x40000>;
                        clock-names = "du.0", "du.1";
                        resets = <&cpg 724>;
                        reset-names = "du.0";
+
+                       renesas,cmms = <&cmm0>, <&cmm1>;
                        vsps = <&vspd0 0>, <&vspd1 0>;
+
                        status = "disabled";
 
                        ports {
diff --git a/arch/arm64/boot/dts/renesas/rzg2-advantech-idk-1110wr-panel.dtsi b/arch/arm64/boot/dts/renesas/rzg2-advantech-idk-1110wr-panel.dtsi
new file mode 100644 (file)
index 0000000..bcc2117
--- /dev/null
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Advantech idk-1110wr LVDS panel connected
+ * to RZ/G2 boards
+ *
+ * Copyright (C) 2019 Renesas Electronics Corp.
+ */
+
+/ {
+       panel-lvds {
+               compatible = "advantech,idk-1110wr", "panel-lvds";
+
+               width-mm = <223>;
+               height-mm = <125>;
+
+               data-mapping = "jeida-24";
+
+               panel-timing {
+                       /* 1024x600 @60Hz */
+                       clock-frequency = <51200000>;
+                       hactive = <1024>;
+                       vactive = <600>;
+                       hsync-len = <240>;
+                       hfront-porch = <40>;
+                       hback-porch = <40>;
+                       vfront-porch = <15>;
+                       vback-porch = <10>;
+                       vsync-len = <10>;
+               };
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&lvds_connector>;
+                       };
+               };
+       };
+};
+
+&lvds_connector {
+       remote-endpoint = <&panel_in>;
+};
index 1f18a93..48fb631 100644 (file)
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb
@@ -27,6 +30,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-neo4.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb
index 6eb7407..936ed7d 100644 (file)
@@ -14,7 +14,7 @@
        compatible = "rockchip,px30-evb", "rockchip,px30";
 
        chosen {
-               stdout-path = "serial2:1500000n8";
+               stdout-path = "serial5:115200n8";
        };
 
        adc-keys {
        backlight: backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm1 0 25000 0>;
+               power-supply = <&vcc3v3_lcd>;
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               pinctrl-0 = <&emmc_reset>;
+               pinctrl-names = "default";
+               reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
        };
 
        sdio_pwrseq: sdio-pwrseq {
                reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */
        };
 
-       vcc_phy: vcc-phy-regulator {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc_phy";
-               regulator-always-on;
-               regulator-boot-on;
-       };
-
        vcc5v0_sys: vccsys {
                compatible = "regulator-fixed";
                regulator-name = "vcc5v0_sys";
        };
 };
 
+&cpu0 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+       cpu-supply = <&vdd_arm>;
+};
+
 &display_subsystem {
        status = "okay";
 };
        cap-mmc-highspeed;
        mmc-hs200-1_8v;
        non-removable;
+       mmc-pwrseq = <&emmc_pwrseq>;
+       vmmc-supply = <&vcc_3v0>;
+       vqmmc-supply = <&vccio_flash>;
        status = "okay";
 };
 
 &gmac {
        clock_in_out = "output";
-       phy-supply = <&vcc_phy>;
+       phy-supply = <&vcc_rmii>;
        snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>;
        snps,reset-active-low;
        snps,reset-delays-us = <0 50000 50000>;
 
 &i2c0 {
        status = "okay";
+
+       rk809: pmic@20 {
+               compatible = "rockchip,rk809";
+               reg = <0x20>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int>;
+               rockchip,system-power-controller;
+               wakeup-source;
+               #clock-cells = <0>;
+               clock-output-names = "xin32k";
+
+               vcc1-supply = <&vcc5v0_sys>;
+               vcc2-supply = <&vcc5v0_sys>;
+               vcc3-supply = <&vcc5v0_sys>;
+               vcc4-supply = <&vcc5v0_sys>;
+               vcc5-supply = <&vcc3v3_sys>;
+               vcc6-supply = <&vcc3v3_sys>;
+               vcc7-supply = <&vcc3v3_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc5v0_sys>;
+
+               regulators {
+                       vdd_log: DCDC_REG1 {
+                               regulator-name = "vdd_log";
+                               regulator-min-microvolt = <950000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <950000>;
+                               };
+                       };
+
+                       vdd_arm: DCDC_REG2 {
+                               regulator-name = "vdd_arm";
+                               regulator-min-microvolt = <950000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <950000>;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-name = "vcc_ddr";
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_3v0: vcc_rmii: DCDC_REG4 {
+                               regulator-name = "vcc_3v0";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc3v3_sys: DCDC_REG5 {
+                               regulator-name = "vcc3v3_sys";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_1v0: LDO_REG1 {
+                               regulator-name = "vcc_1v0";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc_1v8: vccio_flash: vccio_sdio: LDO_REG2 {
+                               regulator-name = "vcc_1v8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vdd_1v0: LDO_REG3 {
+                               regulator-name = "vdd_1v0";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc3v0_pmu: LDO_REG4 {
+                               regulator-name = "vcc3v0_pmu";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG5 {
+                               regulator-name = "vccio_sd";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_sd: LDO_REG6 {
+                               regulator-name = "vcc_sd";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc2v8_dvp: LDO_REG7 {
+                               regulator-name = "vcc2v8_dvp";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <2800000>;
+                               };
+                       };
+
+                       vcc1v8_dvp: LDO_REG8 {
+                               regulator-name = "vcc1v8_dvp";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc1v5_dvp: LDO_REG9 {
+                               regulator-name = "vcc1v5_dvp";
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <1500000>;
+                               };
+                       };
+
+                       vcc3v3_lcd: SWITCH_REG1 {
+                               regulator-name = "vcc3v3_lcd";
+                               regulator-boot-on;
+                       };
+
+                       vcc5v0_host: SWITCH_REG2 {
+                               regulator-name = "vcc5v0_host";
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+
+       sensor@d {
+               compatible = "asahi-kasei,ak8963";
+               reg = <0x0d>;
+               gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+               vdd-supply = <&vcc3v0_pmu>;
+               mount-matrix = "1", /* x0 */
+                              "0", /* y0 */
+                              "0", /* z0 */
+                              "0", /* x1 */
+                              "1", /* y1 */
+                              "0", /* z1 */
+                              "0", /* x2 */
+                              "0", /* y2 */
+                              "1"; /* z2 */
+       };
+
+       touchscreen@14 {
+               compatible = "goodix,gt1151";
+               reg = <0x14>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PA5 IRQ_TYPE_LEVEL_LOW>;
+               irq-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+               VDDIO-supply = <&vcc3v3_lcd>;
+       };
+
+       sensor@4c {
+               compatible = "fsl,mma7660";
+               reg = <0x4c>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PB7 IRQ_TYPE_LEVEL_LOW>;
+       };
 };
 
 &i2s1_2ch {
 
 &io_domains {
        status = "okay";
+
+       vccio1-supply = <&vccio_sdio>;
+       vccio2-supply = <&vccio_sd>;
+       vccio3-supply = <&vcc_3v0>;
+       vccio4-supply = <&vcc3v0_pmu>;
+       vccio5-supply = <&vcc_3v0>;
+       vccio6-supply = <&vccio_flash>;
 };
 
 &pinctrl {
                };
        };
 
+       emmc {
+               emmc_reset: emmc-reset {
+                       rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
        pmic {
                pmic_int: pmic_int {
                        rockchip,pins =
 
 &pmu_io_domains {
        status = "okay";
+
+       pmuio1-supply = <&vcc3v0_pmu>;
+       pmuio2-supply = <&vcc3v0_pmu>;
 };
 
 &pwm1 {
 };
 
 &saradc {
+       vref-supply = <&vcc_1v8>;
        status = "okay";
 };
 
        sd-uhs-sdr25;
        sd-uhs-sdr50;
        sd-uhs-sdr104;
+       vmmc-supply = <&vcc_sd>;
+       vqmmc-supply = <&vccio_sd>;
        status = "okay";
 };
 
        status = "okay";
 };
 
+&u2phy {
+       status = "okay";
+
+       u2phy_host: host-port {
+               status = "okay";
+       };
+
+       u2phy_otg: otg-port {
+               status = "okay";
+       };
+};
+
 &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart1_xfer &uart1_cts>;
        status = "okay";
 };
 
-&uart2 {
+&uart5 {
        status = "okay";
 };
 
index eb992d6..8812b70 100644 (file)
                status = "disabled";
        };
 
-       firmware {
-               optee {
-                       compatible = "linaro,optee-tz";
-                       method = "smc";
-               };
-       };
-
        gmac_clkin: external-gmac-clock {
                compatible = "fixed-clock";
                clock-frequency = <50000000>;
                clock-output-names = "xin24m";
        };
 
-       xin32k: xin32k {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <32768>;
-               clock-output-names = "xin32k";
-       };
-
        pmu: power-management@ff000000 {
                compatible = "rockchip,px30-pmu", "syscon", "simple-mfd";
                reg = <0x0 0xff000000 0x0 0x1000>;
                status = "disabled";
        };
 
+       otp: nvmem@ff290000 {
+               compatible = "rockchip,px30-otp";
+               reg = <0x0 0xff290000 0x0 0x4000>;
+               clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>,
+                        <&cru PCLK_OTP_PHY>;
+               clock-names = "otp", "apb_pclk", "phy";
+               resets = <&cru SRST_OTP_PHY>;
+               reset-names = "phy";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               /* Data cells */
+               cpu_id: id@7 {
+                       reg = <0x07 0x10>;
+               };
+               cpu_leakage: cpu-leakage@17 {
+                       reg = <0x17 0x1>;
+               };
+               performance: performance@1e {
+                       reg = <0x1e 0x1>;
+                       bits = <4 3>;
+               };
+       };
+
        cru: clock-controller@ff2b0000 {
                compatible = "rockchip,px30-cru";
                reg = <0x0 0xff2b0000 0x0 0x1000>;
+               clocks = <&xin24m>, <&pmucru PLL_GPLL>;
+               clock-names = "xin24m", "gpll";
                rockchip,grf = <&grf>;
                #clock-cells = <1>;
                #reset-cells = <1>;
 
-               assigned-clocks = <&cru PLL_NPLL>;
-               assigned-clock-rates = <1188000000>;
+               assigned-clocks = <&cru PLL_NPLL>,
+                       <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>,
+                       <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>,
+                       <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>;
+
+               assigned-clock-rates = <1188000000>,
+                       <200000000>, <200000000>,
+                       <150000000>, <150000000>,
+                       <100000000>, <200000000>;
        };
 
        pmucru: clock-controller@ff2bc000 {
                compatible = "rockchip,px30-pmucru";
                reg = <0x0 0xff2bc000 0x0 0x1000>;
+               clocks = <&xin24m>;
+               clock-names = "xin24m";
                rockchip,grf = <&grf>;
                #clock-cells = <1>;
                #reset-cells = <1>;
 
                assigned-clocks =
                        <&pmucru PLL_GPLL>, <&pmucru PCLK_PMU_PRE>,
-                       <&pmucru SCLK_WIFI_PMU>, <&cru ARMCLK>,
-                       <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>,
-                       <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>,
-                       <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>;
+                       <&pmucru SCLK_WIFI_PMU>;
                assigned-clock-rates =
                        <1200000000>, <100000000>,
-                       <26000000>, <600000000>,
-                       <200000000>, <200000000>,
-                       <150000000>, <150000000>,
-                       <100000000>, <200000000>;
+                       <26000000>;
+       };
+
+       usb2phy_grf: syscon@ff2c0000 {
+               compatible = "rockchip,px30-usb2phy-grf", "syscon",
+                            "simple-mfd";
+               reg = <0x0 0xff2c0000 0x0 0x10000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               u2phy: usb2-phy@100 {
+                       compatible = "rockchip,px30-usb2phy";
+                       reg = <0x100 0x20>;
+                       clocks = <&pmucru SCLK_USBPHY_REF>;
+                       clock-names = "phyclk";
+                       #clock-cells = <0>;
+                       assigned-clocks = <&cru USB480M>;
+                       assigned-clock-parents = <&u2phy>;
+                       clock-output-names = "usb480m_phy";
+                       status = "disabled";
+
+                       u2phy_host: host-port {
+                               #phy-cells = <0>;
+                               interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "linestate";
+                               status = "disabled";
+                       };
+
+                       u2phy_otg: otg-port {
+                               #phy-cells = <0>;
+                               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "otg-bvalid", "otg-id",
+                                                 "linestate";
+                               status = "disabled";
+                       };
+               };
        };
 
        usb20_otg: usb@ff300000 {
                g-rx-fifo-size = <280>;
                g-tx-fifo-size = <256 128 128 64 32 16>;
                g-use-dma;
+               phys = <&u2phy_otg>;
+               phy-names = "usb2-phy";
                power-domains = <&power PX30_PD_USB>;
                status = "disabled";
        };
                interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_HOST>;
                clock-names = "usbhost";
+               phys = <&u2phy_host>;
+               phy-names = "usb";
                power-domains = <&power PX30_PD_USB>;
                status = "disabled";
        };
                interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_HOST>;
                clock-names = "usbhost";
+               phys = <&u2phy_host>;
+               phy-names = "usb";
                power-domains = <&power PX30_PD_USB>;
                status = "disabled";
        };
                clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
                power-domains = <&power PX30_PD_MMC_NAND>;
                status = "disabled";
        };
                interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "vopb_mmu";
                clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>;
-               clock-names = "aclk", "hclk";
+               clock-names = "aclk", "iface";
                power-domains = <&power PX30_PD_VO>;
                #iommu-cells = <0>;
                status = "disabled";
                interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "vopl_mmu";
                clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>;
-               clock-names = "aclk", "hclk";
+               clock-names = "aclk", "iface";
                power-domains = <&power PX30_PD_VO>;
                #iommu-cells = <0>;
                status = "disabled";
                                rockchip,pins =
                                        <0 RK_PB5 1 &pcfg_pull_none>;
                        };
-
-                       uart0_rts_gpio: uart0-rts-gpio {
-                               rockchip,pins =
-                                       <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-                       };
                };
 
                uart1 {
                                rockchip,pins =
                                        <1 RK_PC3 1 &pcfg_pull_none>;
                        };
-
-                       uart1_rts_gpio: uart1-rts-gpio {
-                               rockchip,pins =
-                                       <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
-                       };
                };
 
                uart2-m0 {
                                rockchip,pins =
                                        <0 RK_PC3 2 &pcfg_pull_none>;
                        };
-
-                       uart3m0_rts_gpio: uart3m0-rts-gpio {
-                               rockchip,pins =
-                                       <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
-                       };
                };
 
                uart3-m1 {
                                rockchip,pins =
                                        <1 RK_PB5 2 &pcfg_pull_none>;
                        };
-
-                       uart3m1_rts_gpio: uart3m1-rts-gpio {
-                               rockchip,pins =
-                                       <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-                       };
                };
 
                uart4 {
                                        <1 RK_PD4 1 &pcfg_pull_up_8ma>,
                                        <1 RK_PD5 1 &pcfg_pull_up_8ma>;
                        };
-
-                       sdmmc_gpio: sdmmc-gpio {
-                               rockchip,pins =
-                                       <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
-                                       <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
-                                       <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
-                                       <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
-                                       <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
-                                       <1 RK_PD7 RK_FUNC_GPIO &pcfg_pull_up_4ma>;
-                       };
                };
 
                sdio {
                                        <1 RK_PD0 1 &pcfg_pull_up>,
                                        <1 RK_PD1 1 &pcfg_pull_up>;
                        };
-
-                       sdio_gpio: sdio-gpio {
-                               rockchip,pins =
-                                       <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>,
-                                       <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>,
-                                       <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>,
-                                       <1 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>,
-                                       <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>,
-                                       <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
-                       };
                };
 
                emmc {
                                        <1 RK_PB2 2 &pcfg_pull_up_8ma>;
                        };
 
-                       emmc_pwren: emmc-pwren {
-                               rockchip,pins =
-                                       <1 RK_PB0 2 &pcfg_pull_none>;
-                       };
-
                        emmc_rstnout: emmc-rstnout {
                                rockchip,pins =
                                        <1 RK_PB3 2 &pcfg_pull_none>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb.dts
new file mode 100644 (file)
index 0000000..9b4f855
--- /dev/null
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rk3308.dtsi"
+
+/ {
+       model = "Rockchip RK3308 EVB";
+       compatible = "rockchip,rk3308-evb", "rockchip,rk3308";
+
+       chosen {
+               stdout-path = "serial4:1500000n8";
+       };
+
+       adc-keys0 {
+               compatible = "adc-keys";
+               io-channels = <&saradc 0>;
+               io-channel-names = "buttons";
+               poll-interval = <100>;
+               keyup-threshold-microvolt = <1800000>;
+
+               func-key {
+                       linux,code = <KEY_FN>;
+                       label = "function";
+                       press-threshold-microvolt = <18000>;
+               };
+       };
+
+       adc-keys1 {
+               compatible = "adc-keys";
+               io-channels = <&saradc 1>;
+               io-channel-names = "buttons";
+               poll-interval = <100>;
+               keyup-threshold-microvolt = <1800000>;
+
+               esc-key {
+                       linux,code = <KEY_MICMUTE>;
+                       label = "micmute";
+                       press-threshold-microvolt = <1130000>;
+               };
+
+               home-key {
+                       linux,code = <KEY_MODE>;
+                       label = "mode";
+                       press-threshold-microvolt = <901000>;
+               };
+
+               menu-key {
+                       linux,code = <KEY_PLAY>;
+                       label = "play";
+                       press-threshold-microvolt = <624000>;
+               };
+
+               vol-down-key {
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       label = "volume down";
+                       press-threshold-microvolt = <300000>;
+               };
+
+               vol-up-key {
+                       linux,code = <KEY_VOLUMEUP>;
+                       label = "volume up";
+                       press-threshold-microvolt = <18000>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               autorepeat;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwr_key>;
+
+               power {
+                       gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       label = "GPIO Key Power";
+                       debounce-interval = <100>;
+                       wakeup-source;
+               };
+       };
+
+       vcc12v_dcin: vcc12v-dcin {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc12v_dcin";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vcc5v0_sys: vcc5v0-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc12v_dcin>;
+       };
+
+       vccio_sdio: vcc_1v8: vcc-1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_1v8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_io>;
+       };
+
+       vcc_ddr: vcc-ddr {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_ddr";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc_io: vcc-io {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_io";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vccio_flash: vccio-flash {
+               compatible = "regulator-fixed";
+               regulator-name = "vccio_flash";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_io>;
+       };
+
+       vcc5v0_host: vcc5v0-host {
+               compatible = "regulator-fixed";
+               gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb_drv>;
+               regulator-name = "vbus_host";
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vdd_core: vdd-core {
+               compatible = "pwm-regulator";
+               pwms = <&pwm0 0 5000 1>;
+               regulator-name = "vdd_core";
+               regulator-min-microvolt = <827000>;
+               regulator-max-microvolt = <1340000>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-settling-time-up-us = <250>;
+               pwm-supply = <&vcc5v0_sys>;
+       };
+
+       vdd_log: vdd-log {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_log";
+               regulator-min-microvolt = <1050000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vdd_1v0: vdd-1v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_1v0";
+               regulator-min-microvolt = <1000000>;
+               regulator-max-microvolt = <1000000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_core>;
+};
+
+&saradc {
+       status = "okay";
+       vref-supply = <&vcc_1v8>;
+};
+
+&pinctrl {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rtc_32k>;
+
+       buttons {
+               pwr_key: pwr-key {
+                       rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>;
+               };
+       };
+
+       usb {
+               usb_drv: usb-drv {
+                       rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
+               };
+       };
+
+       sdio-pwrseq {
+               wifi_enable_h: wifi-enable-h {
+                       rockchip,pins = <0 RK_PA2 0 &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+       pinctrl-0 = <&pwm0_pin_pull_down>;
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart4_xfer>;
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
new file mode 100644 (file)
index 0000000..aa25635
--- /dev/null
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+#include "rk3308.dtsi"
+
+/ {
+       model = "Firefly ROC-RK3308-CC board";
+       compatible = "firefly,roc-rk3308-cc", "rockchip,rk3308";
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       ir_rx {
+               compatible = "gpio-ir-receiver";
+               gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&ir_recv_pin>;
+       };
+
+       ir_tx {
+               compatible = "pwm-ir-tx";
+               pwms = <&pwm5 0 25000 0>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               power {
+                       label = "firefly:red:power";
+                       linux,default-trigger = "ir-power-click";
+                       default-state = "on";
+                       gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+               };
+
+               user {
+                       label = "firefly:blue:user";
+                       linux,default-trigger = "ir-user-click";
+                       default-state = "off";
+                       gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       typec_vcc5v: typec-vcc5v {
+               compatible = "regulator-fixed";
+               regulator-name = "typec_vcc5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vcc5v0_sys: vcc5v0-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&typec_vcc5v>;
+       };
+
+       vcc_io: vcc-io {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_io";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc_sdmmc: vcc-sdmmc {
+               compatible = "regulator-gpio";
+               regulator-name = "vcc_sdmmc";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x0
+                         3300000 0x1>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc_sd: vcc-sd {
+               compatible = "regulator-fixed";
+               gpio = <&gpio4 RK_PD6 GPIO_ACTIVE_LOW>;
+               regulator-name = "vcc_sd";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vim-supply = <&vcc_io>;
+       };
+
+       vdd_core: vdd-core {
+               compatible = "pwm-regulator";
+               pwms = <&pwm0 0 5000 1>;
+               regulator-name = "vdd_core";
+               regulator-min-microvolt = <827000>;
+               regulator-max-microvolt = <1340000>;
+               regulator-init-microvolt = <1015000>;
+               regulator-settling-time-up-us = <250>;
+               regulator-always-on;
+               regulator-boot-on;
+               pwm-supply = <&vcc5v0_sys>;
+       };
+
+       vdd_log: vdd-log {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_log";
+               regulator-min-microvolt = <1050000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_core>;
+};
+
+&emmc {
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       disable-wp;
+       mmc-hs200-1_8v;
+       non-removable;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       status = "okay";
+
+       rtc: rtc@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+               #clock-cells = <0>;
+       };
+};
+
+&pwm5 {
+       status = "okay";
+       pinctrl-names = "active";
+       pinctrl-0 = <&pwm5_pin_pull_down>;
+};
+
+&pinctrl {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rtc_32k>;
+
+       ir-receiver {
+               ir_recv_pin: ir-recv-pin  {
+                       rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       buttons {
+               pwr_key: pwr-key {
+                       rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+       pinctrl-0 = <&pwm0_pin_pull_down>;
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       card-detect-delay = <300>;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vcc_sd>;
+       vqmmc-supply = <&vcc_sdmmc>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
new file mode 100644 (file)
index 0000000..8bdc66c
--- /dev/null
@@ -0,0 +1,1739 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ */
+
+#include <dt-bindings/clock/rk3308-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,boot-mode.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+       compatible = "rockchip,rk3308";
+
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
+                       dynamic-power-coefficient = <90>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+                       next-level-cache = <&l2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       operating-points-v2 = <&cpu0_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+                       next-level-cache = <&l2>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x2>;
+                       enable-method = "psci";
+                       operating-points-v2 = <&cpu0_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+                       next-level-cache = <&l2>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x3>;
+                       enable-method = "psci";
+                       operating-points-v2 = <&cpu0_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+                       next-level-cache = <&l2>;
+               };
+
+               idle-states {
+                       entry-method = "psci";
+
+                       CPU_SLEEP: cpu-sleep {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x0010000>;
+                               entry-latency-us = <120>;
+                               exit-latency-us = <250>;
+                               min-residency-us = <900>;
+                       };
+               };
+
+               l2: l2-cache {
+                       compatible = "cache";
+               };
+       };
+
+       cpu0_opp_table: cpu0-opp-table {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-408000000 {
+                       opp-hz = /bits/ 64 <408000000>;
+                       opp-microvolt = <950000 950000 1340000>;
+                       clock-latency-ns = <40000>;
+                       opp-suspend;
+               };
+               opp-600000000 {
+                       opp-hz = /bits/ 64 <600000000>;
+                       opp-microvolt = <950000 950000 1340000>;
+                       clock-latency-ns = <40000>;
+               };
+               opp-816000000 {
+                       opp-hz = /bits/ 64 <816000000>;
+                       opp-microvolt = <1025000 1025000 1340000>;
+                       clock-latency-ns = <40000>;
+               };
+               opp-1008000000 {
+                       opp-hz = /bits/ 64 <1008000000>;
+                       opp-microvolt = <1125000 1125000 1340000>;
+                       clock-latency-ns = <40000>;
+               };
+       };
+
+       arm-pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
+       mac_clkin: external-mac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <50000000>;
+               clock-output-names = "mac_clkin";
+               #clock-cells = <0>;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       xin24m: xin24m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+               clock-output-names = "xin24m";
+       };
+
+       grf: grf@ff000000 {
+               compatible = "rockchip,rk3308-grf", "syscon", "simple-mfd";
+               reg = <0x0 0xff000000 0x0 0x10000>;
+
+               reboot-mode {
+                       compatible = "syscon-reboot-mode";
+                       offset = <0x500>;
+                       mode-bootloader = <BOOT_BL_DOWNLOAD>;
+                       mode-loader = <BOOT_BL_DOWNLOAD>;
+                       mode-normal = <BOOT_NORMAL>;
+                       mode-recovery = <BOOT_RECOVERY>;
+                       mode-fastboot = <BOOT_FASTBOOT>;
+               };
+       };
+
+       detect_grf: syscon@ff00b000 {
+               compatible = "rockchip,rk3308-detect-grf", "syscon", "simple-mfd";
+               reg = <0x0 0xff00b000 0x0 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+
+       core_grf: syscon@ff00c000 {
+               compatible = "rockchip,rk3308-core-grf", "syscon", "simple-mfd";
+               reg = <0x0 0xff00c000 0x0 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+
+       i2c0: i2c@ff040000 {
+               compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff040000 0x0 0x1000>;
+               clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c0_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@ff050000 {
+               compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff050000 0x0 0x1000>;
+               clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c1_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@ff060000 {
+               compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff060000 0x0 0x1000>;
+               clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@ff070000 {
+               compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff070000 0x0 0x1000>;
+               clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c3m0_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       wdt: watchdog@ff080000 {
+               compatible = "snps,dw-wdt";
+               reg = <0x0 0xff080000 0x0 0x100>;
+               clocks = <&cru PCLK_WDT>;
+               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       uart0: serial@ff0a0000 {
+               compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff0a0000 0x0 0x100>;
+               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+               clock-names = "baudclk", "apb_pclk";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+               status = "disabled";
+       };
+
+       uart1: serial@ff0b0000 {
+               compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff0b0000 0x0 0x100>;
+               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+               clock-names = "baudclk", "apb_pclk";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
+               status = "disabled";
+       };
+
+       uart2: serial@ff0c0000 {
+               compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff0c0000 0x0 0x100>;
+               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+               clock-names = "baudclk", "apb_pclk";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart2m0_xfer>;
+               status = "disabled";
+       };
+
+       uart3: serial@ff0d0000 {
+               compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff0d0000 0x0 0x100>;
+               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+               clock-names = "baudclk", "apb_pclk";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart3_xfer>;
+               status = "disabled";
+       };
+
+       uart4: serial@ff0e0000 {
+               compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff0e0000 0x0 0x100>;
+               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+               clock-names = "baudclk", "apb_pclk";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
+               status = "disabled";
+       };
+
+       spi0: spi@ff120000 {
+               compatible = "rockchip,rk3308-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff120000 0x0 0x1000>;
+               interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+               clock-names = "spiclk", "apb_pclk";
+               dmas = <&dmac0 0>, <&dmac0 1>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi0_clk &spi0_csn0 &spi0_miso &spi0_mosi>;
+               status = "disabled";
+       };
+
+       spi1: spi@ff130000 {
+               compatible = "rockchip,rk3308-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff130000 0x0 0x1000>;
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+               clock-names = "spiclk", "apb_pclk";
+               dmas = <&dmac0 2>, <&dmac0 3>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_miso &spi1_mosi>;
+               status = "disabled";
+       };
+
+       spi2: spi@ff140000 {
+               compatible = "rockchip,rk3308-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff140000 0x0 0x1000>;
+               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
+               clock-names = "spiclk", "apb_pclk";
+               dmas = <&dmac1 16>, <&dmac1 17>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi2_clk &spi2_csn0 &spi2_miso &spi2_mosi>;
+               status = "disabled";
+       };
+
+       pwm8: pwm@ff160000 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff160000 0x0 0x10>;
+               clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm8_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm9: pwm@ff160010 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff160010 0x0 0x10>;
+               clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm9_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm10: pwm@ff160020 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff160020 0x0 0x10>;
+               clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm10_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm11: pwm@ff160030 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff160030 0x0 0x10>;
+               clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm11_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm4: pwm@ff170000 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff170000 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm4_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm5: pwm@ff170010 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff170010 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm5_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm6: pwm@ff170020 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff170020 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm6_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm7: pwm@ff170030 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff170030 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm7_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm0: pwm@ff180000 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff180000 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm0_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm1: pwm@ff180010 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff180010 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm1_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm2: pwm@ff180020 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff180020 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm2_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm3: pwm@ff180030 {
+               compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff180030 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm3_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       rktimer: rktimer@ff1a0000 {
+               compatible = "rockchip,rk3288-timer";
+               reg = <0x0 0xff1a0000 0x0 0x20>;
+               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>;
+               clock-names = "pclk", "timer";
+       };
+
+       saradc: saradc@ff1e0000 {
+               compatible = "rockchip,rk3308-saradc", "rockchip,rk3399-saradc";
+               reg = <0x0 0xff1e0000 0x0 0x100>;
+               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+               clock-names = "saradc", "apb_pclk";
+               #io-channel-cells = <1>;
+               resets = <&cru SRST_SARADC_P>;
+               reset-names = "saradc-apb";
+               status = "disabled";
+       };
+
+       amba {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               dmac0: dma-controller@ff2c0000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x0 0xff2c0000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru ACLK_DMAC0>;
+                       clock-names = "apb_pclk";
+                       #dma-cells = <1>;
+               };
+
+               dmac1: dma-controller@ff2d0000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x0 0xff2d0000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru ACLK_DMAC1>;
+                       clock-names = "apb_pclk";
+                       #dma-cells = <1>;
+               };
+       };
+
+       i2s_2ch_0: i2s@ff350000 {
+               compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s";
+               reg = <0x0 0xff350000 0x0 0x1000>;
+               interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_I2S0_2CH>, <&cru HCLK_I2S0_2CH>;
+               clock-names = "i2s_clk", "i2s_hclk";
+               dmas = <&dmac1 8>, <&dmac1 9>;
+               dma-names = "tx", "rx";
+               resets = <&cru SRST_I2S0_2CH_M>, <&cru SRST_I2S0_2CH_H>;
+               reset-names = "reset-m", "reset-h";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s_2ch_0_sclk
+                            &i2s_2ch_0_lrck
+                            &i2s_2ch_0_sdi
+                            &i2s_2ch_0_sdo>;
+               status = "disabled";
+       };
+
+       i2s_2ch_1: i2s@ff360000 {
+               compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s";
+               reg = <0x0 0xff360000 0x0 0x1000>;
+               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_I2S1_2CH>, <&cru HCLK_I2S1_2CH>;
+               clock-names = "i2s_clk", "i2s_hclk";
+               dmas = <&dmac1 11>;
+               dma-names = "rx";
+               resets = <&cru SRST_I2S1_2CH_M>, <&cru SRST_I2S1_2CH_H>;
+               reset-names = "reset-m", "reset-h";
+               status = "disabled";
+       };
+
+       spdif_tx: spdif-tx@ff3a0000 {
+               compatible = "rockchip,rk3308-spdif", "rockchip,rk3328-spdif";
+               reg = <0x0 0xff3a0000 0x0 0x1000>;
+               interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_SPDIF_TX>, <&cru HCLK_SPDIFTX>;
+               clock-names = "mclk", "hclk";
+               dmas = <&dmac1 13>;
+               dma-names = "tx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spdif_out>;
+               status = "disabled";
+       };
+
+       sdmmc: dwmmc@ff480000 {
+               compatible = "rockchip,rk3308-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xff480000 0x0 0x4000>;
+               interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+               bus-width = <4>;
+               clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+                        <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               fifo-depth = <0x100>;
+               max-frequency = <150000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+               status = "disabled";
+       };
+
+       emmc: dwmmc@ff490000 {
+               compatible = "rockchip,rk3308-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xff490000 0x0 0x4000>;
+               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+               bus-width = <8>;
+               clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+                        <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               fifo-depth = <0x100>;
+               max-frequency = <150000000>;
+               status = "disabled";
+       };
+
+       sdio: dwmmc@ff4a0000 {
+               compatible = "rockchip,rk3308-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xff4a0000 0x0 0x4000>;
+               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+               bus-width = <4>;
+               clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+                        <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               fifo-depth = <0x100>;
+               max-frequency = <150000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>;
+               status = "disabled";
+       };
+
+       cru: clock-controller@ff500000 {
+               compatible = "rockchip,rk3308-cru";
+               reg = <0x0 0xff500000 0x0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               rockchip,grf = <&grf>;
+
+               assigned-clocks = <&cru SCLK_RTC32K>;
+               assigned-clock-rates = <32768>;
+       };
+
+       gic: interrupt-controller@ff580000 {
+               compatible = "arm,gic-400";
+               reg = <0x0 0xff581000 0x0 0x1000>,
+                     <0x0 0xff582000 0x0 0x2000>,
+                     <0x0 0xff584000 0x0 0x2000>,
+                     <0x0 0xff586000 0x0 0x2000>;
+               interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               #address-cells = <0>;
+       };
+
+       sram: sram@fff80000 {
+               compatible = "mmio-sram";
+               reg = <0x0 0xfff80000 0x0 0x40000>;
+               ranges = <0 0x0 0xfff80000 0x40000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               /* reserved for ddr dvfs and system suspend/resume */
+               ddr-sram@0 {
+                       reg = <0x0 0x8000>;
+               };
+
+               /* reserved for vad audio buffer */
+               vad_sram: vad-sram@8000 {
+                       reg = <0x8000 0x38000>;
+               };
+       };
+
+       pinctrl: pinctrl {
+               compatible = "rockchip,rk3308-pinctrl";
+               rockchip,grf = <&grf>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               gpio0: gpio0@ff220000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff220000 0x0 0x100>;
+                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio1: gpio1@ff230000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff230000 0x0 0x100>;
+                       interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio2: gpio2@ff240000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff240000 0x0 0x100>;
+                       interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO2>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio3: gpio3@ff250000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff250000 0x0 0x100>;
+                       interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO3>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio4: gpio4@ff260000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff260000 0x0 0x100>;
+                       interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO4>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               pcfg_pull_up: pcfg-pull-up {
+                       bias-pull-up;
+               };
+
+               pcfg_pull_down: pcfg-pull-down {
+                       bias-pull-down;
+               };
+
+               pcfg_pull_none: pcfg-pull-none {
+                       bias-disable;
+               };
+
+               pcfg_pull_none_2ma: pcfg-pull-none-2ma {
+                       bias-disable;
+                       drive-strength = <2>;
+               };
+
+               pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+                       bias-pull-up;
+                       drive-strength = <2>;
+               };
+
+               pcfg_pull_up_4ma: pcfg-pull-up-4ma {
+                       bias-pull-up;
+                       drive-strength = <4>;
+               };
+
+               pcfg_pull_none_4ma: pcfg-pull-none-4ma {
+                       bias-disable;
+                       drive-strength = <4>;
+               };
+
+               pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+                       bias-pull-down;
+                       drive-strength = <4>;
+               };
+
+               pcfg_pull_none_8ma: pcfg-pull-none-8ma {
+                       bias-disable;
+                       drive-strength = <8>;
+               };
+
+               pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+                       bias-pull-up;
+                       drive-strength = <8>;
+               };
+
+               pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+                       bias-disable;
+                       drive-strength = <12>;
+               };
+
+               pcfg_pull_up_12ma: pcfg-pull-up-12ma {
+                       bias-pull-up;
+                       drive-strength = <12>;
+               };
+
+               pcfg_pull_none_smt: pcfg-pull-none-smt {
+                       bias-disable;
+                       input-schmitt-enable;
+               };
+
+               pcfg_output_high: pcfg-output-high {
+                       output-high;
+               };
+
+               pcfg_output_low: pcfg-output-low {
+                       output-low;
+               };
+
+               pcfg_input_high: pcfg-input-high {
+                       bias-pull-up;
+                       input-enable;
+               };
+
+               pcfg_input: pcfg-input {
+                       input-enable;
+               };
+
+               emmc {
+                       emmc_clk: emmc-clk {
+                               rockchip,pins =
+                                       <3 RK_PB1 2 &pcfg_pull_none_8ma>;
+                       };
+
+                       emmc_cmd: emmc-cmd {
+                               rockchip,pins =
+                                       <3 RK_PB0 2 &pcfg_pull_up_8ma>;
+                       };
+
+                       emmc_pwren: emmc-pwren {
+                               rockchip,pins =
+                                       <3 RK_PB3 2 &pcfg_pull_none>;
+                       };
+
+                       emmc_rstn: emmc-rstn {
+                               rockchip,pins =
+                                       <3 RK_PB2 2 &pcfg_pull_none>;
+                       };
+
+                       emmc_bus1: emmc-bus1 {
+                               rockchip,pins =
+                                       <3 RK_PA0 2 &pcfg_pull_up_8ma>;
+                       };
+
+                       emmc_bus4: emmc-bus4 {
+                               rockchip,pins =
+                                       <3 RK_PA0 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA1 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA2 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA3 2 &pcfg_pull_up_8ma>;
+                       };
+
+                       emmc_bus8: emmc-bus8 {
+                               rockchip,pins =
+                                       <3 RK_PA0 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA1 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA2 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA3 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA4 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA5 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA6 2 &pcfg_pull_up_8ma>,
+                                       <3 RK_PA7 2 &pcfg_pull_up_8ma>;
+                       };
+               };
+
+               flash {
+                       flash_csn0: flash-csn0 {
+                               rockchip,pins =
+                                       <3 RK_PB5 1 &pcfg_pull_none>;
+                       };
+
+                       flash_rdy: flash-rdy {
+                               rockchip,pins =
+                                       <3 RK_PB4 1 &pcfg_pull_none>;
+                       };
+
+                       flash_ale: flash-ale {
+                               rockchip,pins =
+                                       <3 RK_PB3 1 &pcfg_pull_none>;
+                       };
+
+                       flash_cle: flash-cle {
+                               rockchip,pins =
+                                       <3 RK_PB1 1 &pcfg_pull_none>;
+                       };
+
+                       flash_wrn: flash-wrn {
+                               rockchip,pins =
+                                       <3 RK_PB0 1 &pcfg_pull_none>;
+                       };
+
+                       flash_rdn: flash-rdn {
+                               rockchip,pins =
+                                       <3 RK_PB2 1 &pcfg_pull_none>;
+                       };
+
+                       flash_bus8: flash-bus8 {
+                               rockchip,pins =
+                                       <3 RK_PA0 1 &pcfg_pull_up_12ma>,
+                                       <3 RK_PA1 1 &pcfg_pull_up_12ma>,
+                                       <3 RK_PA2 1 &pcfg_pull_up_12ma>,
+                                       <3 RK_PA3 1 &pcfg_pull_up_12ma>,
+                                       <3 RK_PA4 1 &pcfg_pull_up_12ma>,
+                                       <3 RK_PA5 1 &pcfg_pull_up_12ma>,
+                                       <3 RK_PA6 1 &pcfg_pull_up_12ma>,
+                                       <3 RK_PA7 1 &pcfg_pull_up_12ma>;
+                       };
+               };
+
+               gmac {
+                       rmii_pins: rmii-pins {
+                               rockchip,pins =
+                                       /* mac_txen */
+                                       <1 RK_PC1 3 &pcfg_pull_none_12ma>,
+                                       /* mac_txd1 */
+                                       <1 RK_PC3 3 &pcfg_pull_none_12ma>,
+                                       /* mac_txd0 */
+                                       <1 RK_PC2 3 &pcfg_pull_none_12ma>,
+                                       /* mac_rxd0 */
+                                       <1 RK_PC4 3 &pcfg_pull_none>,
+                                       /* mac_rxd1 */
+                                       <1 RK_PC5 3 &pcfg_pull_none>,
+                                       /* mac_rxer */
+                                       <1 RK_PB7 3 &pcfg_pull_none>,
+                                       /* mac_rxdv */
+                                       <1 RK_PC0 3 &pcfg_pull_none>,
+                                       /* mac_mdio */
+                                       <1 RK_PB6 3 &pcfg_pull_none>,
+                                       /* mac_mdc */
+                                       <1 RK_PB5 3 &pcfg_pull_none>;
+                       };
+
+                       mac_refclk_12ma: mac-refclk-12ma {
+                               rockchip,pins =
+                                       <1 RK_PB4 3 &pcfg_pull_none_12ma>;
+                       };
+
+                       mac_refclk: mac-refclk {
+                               rockchip,pins =
+                                       <1 RK_PB4 3 &pcfg_pull_none>;
+                       };
+               };
+
+               gmac-m1 {
+                       rmiim1_pins: rmiim1-pins {
+                               rockchip,pins =
+                                       /* mac_txen */
+                                       <4 RK_PB7 2 &pcfg_pull_none_12ma>,
+                                       /* mac_txd1 */
+                                       <4 RK_PA5 2 &pcfg_pull_none_12ma>,
+                                       /* mac_txd0 */
+                                       <4 RK_PA4 2 &pcfg_pull_none_12ma>,
+                                       /* mac_rxd0 */
+                                       <4 RK_PA2 2 &pcfg_pull_none>,
+                                       /* mac_rxd1 */
+                                       <4 RK_PA3 2 &pcfg_pull_none>,
+                                       /* mac_rxer */
+                                       <4 RK_PA0 2 &pcfg_pull_none>,
+                                       /* mac_rxdv */
+                                       <4 RK_PA1 2 &pcfg_pull_none>,
+                                       /* mac_mdio */
+                                       <4 RK_PB6 2 &pcfg_pull_none>,
+                                       /* mac_mdc */
+                                       <4 RK_PB5 2 &pcfg_pull_none>;
+                       };
+
+                       macm1_refclk_12ma: macm1-refclk-12ma {
+                               rockchip,pins =
+                                       <4 RK_PB4 2 &pcfg_pull_none_12ma>;
+                       };
+
+                       macm1_refclk: macm1-refclk {
+                               rockchip,pins =
+                                       <4 RK_PB4 2 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c0 {
+                       i2c0_xfer: i2c0-xfer {
+                               rockchip,pins =
+                                       <1 RK_PD0 2 &pcfg_pull_none_smt>,
+                                       <1 RK_PD1 2 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c1 {
+                       i2c1_xfer: i2c1-xfer {
+                               rockchip,pins =
+                                       <0 RK_PB3 1 &pcfg_pull_none_smt>,
+                                       <0 RK_PB4 1 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c2 {
+                       i2c2_xfer: i2c2-xfer {
+                               rockchip,pins =
+                                       <2 RK_PA2 3 &pcfg_pull_none_smt>,
+                                       <2 RK_PA3 3 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c3-m0 {
+                       i2c3m0_xfer: i2c3m0-xfer {
+                               rockchip,pins =
+                                       <0 RK_PB7 2 &pcfg_pull_none_smt>,
+                                       <0 RK_PC0 2 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c3-m1 {
+                       i2c3m1_xfer: i2c3m1-xfer {
+                               rockchip,pins =
+                                       <3 RK_PB4 2 &pcfg_pull_none_smt>,
+                                       <3 RK_PB5 2 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c3-m2 {
+                       i2c3m2_xfer: i2c3m2-xfer {
+                               rockchip,pins =
+                                       <2 RK_PA1 3 &pcfg_pull_none_smt>,
+                                       <2 RK_PA0 3 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2s_2ch_0 {
+                       i2s_2ch_0_mclk: i2s-2ch-0-mclk {
+                               rockchip,pins =
+                                       <4 RK_PB4 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_2ch_0_sclk: i2s-2ch-0-sclk {
+                               rockchip,pins =
+                                       <4 RK_PB5 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_2ch_0_lrck: i2s-2ch-0-lrck {
+                               rockchip,pins =
+                                       <4 RK_PB6 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_2ch_0_sdo: i2s-2ch-0-sdo {
+                               rockchip,pins =
+                                       <4 RK_PB7 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_2ch_0_sdi: i2s-2ch-0-sdi {
+                               rockchip,pins =
+                                       <4 RK_PC0 1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s_8ch_0 {
+                       i2s_8ch_0_mclk: i2s-8ch-0-mclk {
+                               rockchip,pins =
+                                       <2 RK_PA4 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sclktx: i2s-8ch-0-sclktx {
+                               rockchip,pins =
+                                       <2 RK_PA5 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sclkrx: i2s-8ch-0-sclkrx {
+                               rockchip,pins =
+                                       <2 RK_PA6 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_lrcktx: i2s-8ch-0-lrcktx {
+                               rockchip,pins =
+                                       <2 RK_PA7 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_lrckrx: i2s-8ch-0-lrckrx {
+                               rockchip,pins =
+                                       <2 RK_PB0 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdo0: i2s-8ch-0-sdo0 {
+                               rockchip,pins =
+                                       <2 RK_PB1 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdo1: i2s-8ch-0-sdo1 {
+                               rockchip,pins =
+                                       <2 RK_PB2 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdo2: i2s-8ch-0-sdo2 {
+                               rockchip,pins =
+                                       <2 RK_PB3 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdo3: i2s-8ch-0-sdo3 {
+                               rockchip,pins =
+                                       <2 RK_PB4 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdi0: i2s-8ch-0-sdi0 {
+                               rockchip,pins =
+                                       <2 RK_PB5 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdi1: i2s-8ch-0-sdi1 {
+                               rockchip,pins =
+                                       <2 RK_PB6 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdi2: i2s-8ch-0-sdi2 {
+                               rockchip,pins =
+                                       <2 RK_PB7 1 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_0_sdi3: i2s-8ch-0-sdi3 {
+                               rockchip,pins =
+                                       <2 RK_PC0 1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s_8ch_1_m0 {
+                       i2s_8ch_1_m0_mclk: i2s-8ch-1-m0-mclk {
+                               rockchip,pins =
+                                       <1 RK_PA2 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_sclktx: i2s-8ch-1-m0-sclktx {
+                               rockchip,pins =
+                                       <1 RK_PA3 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_sclkrx: i2s-8ch-1-m0-sclkrx {
+                               rockchip,pins =
+                                       <1 RK_PA4 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_lrcktx: i2s-8ch-1-m0-lrcktx {
+                               rockchip,pins =
+                                       <1 RK_PA5 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_lrckrx: i2s-8ch-1-m0-lrckrx {
+                               rockchip,pins =
+                                       <1 RK_PA6 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_sdo0: i2s-8ch-1-m0-sdo0 {
+                               rockchip,pins =
+                                       <1 RK_PA7 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_sdo1_sdi3: i2s-8ch-1-m0-sdo1-sdi3 {
+                               rockchip,pins =
+                                       <1 RK_PB0 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_sdo2_sdi2: i2s-8ch-1-m0-sdo2-sdi2 {
+                               rockchip,pins =
+                                       <1 RK_PB1 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_sdo3_sdi1: i2s-8ch-1-m0-sdo3_sdi1 {
+                               rockchip,pins =
+                                       <1 RK_PB2 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m0_sdi0: i2s-8ch-1-m0-sdi0 {
+                               rockchip,pins =
+                                       <1 RK_PB3 2 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s_8ch_1_m1 {
+                       i2s_8ch_1_m1_mclk: i2s-8ch-1-m1-mclk {
+                               rockchip,pins =
+                                       <1 RK_PB4 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_sclktx: i2s-8ch-1-m1-sclktx {
+                               rockchip,pins =
+                                       <1 RK_PB5 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_sclkrx: i2s-8ch-1-m1-sclkrx {
+                               rockchip,pins =
+                                       <1 RK_PB6 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_lrcktx: i2s-8ch-1-m1-lrcktx {
+                               rockchip,pins =
+                                       <1 RK_PB7 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_lrckrx: i2s-8ch-1-m1-lrckrx {
+                               rockchip,pins =
+                                       <1 RK_PC0 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_sdo0: i2s-8ch-1-m1-sdo0 {
+                               rockchip,pins =
+                                       <1 RK_PC1 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_sdo1_sdi3: i2s-8ch-1-m1-sdo1-sdi3 {
+                               rockchip,pins =
+                                       <1 RK_PC2 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_sdo2_sdi2: i2s-8ch-1-m1-sdo2-sdi2 {
+                               rockchip,pins =
+                                       <1 RK_PC3 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_sdo3_sdi1: i2s-8ch-1-m1-sdo3_sdi1 {
+                               rockchip,pins =
+                                       <1 RK_PC4 2 &pcfg_pull_none>;
+                       };
+
+                       i2s_8ch_1_m1_sdi0: i2s-8ch-1-m1-sdi0 {
+                               rockchip,pins =
+                                       <1 RK_PC5 2 &pcfg_pull_none>;
+                       };
+               };
+
+               pdm_m0 {
+                       pdm_m0_clk: pdm-m0-clk {
+                               rockchip,pins =
+                                       <1 RK_PA4 3 &pcfg_pull_none>;
+                       };
+
+                       pdm_m0_sdi0: pdm-m0-sdi0 {
+                               rockchip,pins =
+                                       <1 RK_PB3 3 &pcfg_pull_none>;
+                       };
+
+                       pdm_m0_sdi1: pdm-m0-sdi1 {
+                               rockchip,pins =
+                                       <1 RK_PB2 3 &pcfg_pull_none>;
+                       };
+
+                       pdm_m0_sdi2: pdm-m0-sdi2 {
+                               rockchip,pins =
+                                       <1 RK_PB1 3 &pcfg_pull_none>;
+                       };
+
+                       pdm_m0_sdi3: pdm-m0-sdi3 {
+                               rockchip,pins =
+                                       <1 RK_PB0 3 &pcfg_pull_none>;
+                       };
+               };
+
+               pdm_m1 {
+                       pdm_m1_clk: pdm-m1-clk {
+                               rockchip,pins =
+                                       <1 RK_PB6 4 &pcfg_pull_none>;
+                       };
+
+                       pdm_m1_sdi0: pdm-m1-sdi0 {
+                               rockchip,pins =
+                                       <1 RK_PC5 4 &pcfg_pull_none>;
+                       };
+
+                       pdm_m1_sdi1: pdm-m1-sdi1 {
+                               rockchip,pins =
+                                       <1 RK_PC4 4 &pcfg_pull_none>;
+                       };
+
+                       pdm_m1_sdi2: pdm-m1-sdi2 {
+                               rockchip,pins =
+                                       <1 RK_PC3 4 &pcfg_pull_none>;
+                       };
+
+                       pdm_m1_sdi3: pdm-m1-sdi3 {
+                               rockchip,pins =
+                                       <1 RK_PC2 4 &pcfg_pull_none>;
+                       };
+               };
+
+               pdm_m2 {
+                       pdm_m2_clkm: pdm-m2-clkm {
+                               rockchip,pins =
+                                       <2 RK_PA4 3 &pcfg_pull_none>;
+                       };
+
+                       pdm_m2_clk: pdm-m2-clk {
+                               rockchip,pins =
+                                       <2 RK_PA6 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_m2_sdi0: pdm-m2-sdi0 {
+                               rockchip,pins =
+                                       <2 RK_PB5 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_m2_sdi1: pdm-m2-sdi1 {
+                               rockchip,pins =
+                                       <2 RK_PB6 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_m2_sdi2: pdm-m2-sdi2 {
+                               rockchip,pins =
+                                       <2 RK_PB7 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_m2_sdi3: pdm-m2-sdi3 {
+                               rockchip,pins =
+                                       <2 RK_PC0 2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm0 {
+                       pwm0_pin: pwm0-pin {
+                               rockchip,pins =
+                                       <0 RK_PB5 1 &pcfg_pull_none>;
+                       };
+
+                       pwm0_pin_pull_down: pwm0-pin-pull-down {
+                               rockchip,pins =
+                                       <0 RK_PB5 1 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm1 {
+                       pwm1_pin: pwm1-pin {
+                               rockchip,pins =
+                                       <0 RK_PB6 1 &pcfg_pull_none>;
+                       };
+
+                       pwm1_pin_pull_down: pwm1-pin-pull-down {
+                               rockchip,pins =
+                                       <0 RK_PB6 1 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm2 {
+                       pwm2_pin: pwm2-pin {
+                               rockchip,pins =
+                                       <0 RK_PB7 1 &pcfg_pull_none>;
+                       };
+
+                       pwm2_pin_pull_down: pwm2-pin-pull-down {
+                               rockchip,pins =
+                                       <0 RK_PB7 1 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm3 {
+                       pwm3_pin: pwm3-pin {
+                               rockchip,pins =
+                                       <0 RK_PC0 1 &pcfg_pull_none>;
+                       };
+
+                       pwm3_pin_pull_down: pwm3-pin-pull-down {
+                               rockchip,pins =
+                                       <0 RK_PC0 1 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm4 {
+                       pwm4_pin: pwm4-pin {
+                               rockchip,pins =
+                                       <0 RK_PA1 2 &pcfg_pull_none>;
+                       };
+
+                       pwm4_pin_pull_down: pwm4-pin-pull-down {
+                               rockchip,pins =
+                                       <0 RK_PA1 2 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm5 {
+                       pwm5_pin: pwm5-pin {
+                               rockchip,pins =
+                                       <0 RK_PC1 2 &pcfg_pull_none>;
+                       };
+
+                       pwm5_pin_pull_down: pwm5-pin-pull-down {
+                               rockchip,pins =
+                                       <0 RK_PC1 2 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm6 {
+                       pwm6_pin: pwm6-pin {
+                               rockchip,pins =
+                                       <0 RK_PC2 2 &pcfg_pull_none>;
+                       };
+
+                       pwm6_pin_pull_down: pwm6-pin-pull-down {
+                               rockchip,pins =
+                                       <0 RK_PC2 2 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm7 {
+                       pwm7_pin: pwm7-pin {
+                               rockchip,pins =
+                                       <2 RK_PB0 2 &pcfg_pull_none>;
+                       };
+
+                       pwm7_pin_pull_down: pwm7-pin-pull-down {
+                               rockchip,pins =
+                                       <2 RK_PB0 2 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm8 {
+                       pwm8_pin: pwm8-pin {
+                               rockchip,pins =
+                                       <2 RK_PB2 2 &pcfg_pull_none>;
+                       };
+
+                       pwm8_pin_pull_down: pwm8-pin-pull-down {
+                               rockchip,pins =
+                                       <2 RK_PB2 2 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm9 {
+                       pwm9_pin: pwm9-pin {
+                               rockchip,pins =
+                                       <2 RK_PB3 2 &pcfg_pull_none>;
+                       };
+
+                       pwm9_pin_pull_down: pwm9-pin-pull-down {
+                               rockchip,pins =
+                                       <2 RK_PB3 2 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm10 {
+                       pwm10_pin: pwm10-pin {
+                               rockchip,pins =
+                                       <2 RK_PB4 2 &pcfg_pull_none>;
+                       };
+
+                       pwm10_pin_pull_down: pwm10-pin-pull-down {
+                               rockchip,pins =
+                                       <2 RK_PB4 2 &pcfg_pull_down>;
+                       };
+               };
+
+               pwm11 {
+                       pwm11_pin: pwm11-pin {
+                               rockchip,pins =
+                                       <2 RK_PC0 4 &pcfg_pull_none>;
+                       };
+
+                       pwm11_pin_pull_down: pwm11-pin-pull-down {
+                               rockchip,pins =
+                                       <2 RK_PC0 4 &pcfg_pull_down>;
+                       };
+               };
+
+               rtc {
+                       rtc_32k: rtc-32k {
+                               rockchip,pins =
+                                       <0 RK_PC3 1 &pcfg_pull_none>;
+                       };
+               };
+
+               sdmmc {
+                       sdmmc_clk: sdmmc-clk {
+                               rockchip,pins =
+                                       <4 RK_PD5 1 &pcfg_pull_none_4ma>;
+                       };
+
+                       sdmmc_cmd: sdmmc-cmd {
+                               rockchip,pins =
+                                       <4 RK_PD4 1 &pcfg_pull_up_4ma>;
+                       };
+
+                       sdmmc_det: sdmmc-det {
+                               rockchip,pins =
+                                       <0 RK_PA3 1 &pcfg_pull_up_4ma>;
+                       };
+
+                       sdmmc_pwren: sdmmc-pwren {
+                               rockchip,pins =
+                                       <4 RK_PD6 1 &pcfg_pull_none_4ma>;
+                       };
+
+                       sdmmc_bus1: sdmmc-bus1 {
+                               rockchip,pins =
+                                       <4 RK_PD0 1 &pcfg_pull_up_4ma>;
+                       };
+
+                       sdmmc_bus4: sdmmc-bus4 {
+                               rockchip,pins =
+                                       <4 RK_PD0 1 &pcfg_pull_up_4ma>,
+                                       <4 RK_PD1 1 &pcfg_pull_up_4ma>,
+                                       <4 RK_PD2 1 &pcfg_pull_up_4ma>,
+                                       <4 RK_PD3 1 &pcfg_pull_up_4ma>;
+                       };
+               };
+
+               sdio {
+                       sdio_clk: sdio-clk {
+                               rockchip,pins =
+                                       <4 RK_PA5 1 &pcfg_pull_none_8ma>;
+                       };
+
+                       sdio_cmd: sdio-cmd {
+                               rockchip,pins =
+                                       <4 RK_PA4 1 &pcfg_pull_up_8ma>;
+                       };
+
+                       sdio_pwren: sdio-pwren {
+                               rockchip,pins =
+                                       <0 RK_PA2 1 &pcfg_pull_none_8ma>;
+                       };
+
+                       sdio_wrpt: sdio-wrpt {
+                               rockchip,pins =
+                                       <0 RK_PA1 1 &pcfg_pull_none_8ma>;
+                       };
+
+                       sdio_intn: sdio-intn {
+                               rockchip,pins =
+                                       <0 RK_PA0 1 &pcfg_pull_none_8ma>;
+                       };
+
+                       sdio_bus1: sdio-bus1 {
+                               rockchip,pins =
+                                       <4 RK_PA0 1 &pcfg_pull_up_8ma>;
+                       };
+
+                       sdio_bus4: sdio-bus4 {
+                               rockchip,pins =
+                                       <4 RK_PA0 1 &pcfg_pull_up_8ma>,
+                                       <4 RK_PA1 1 &pcfg_pull_up_8ma>,
+                                       <4 RK_PA2 1 &pcfg_pull_up_8ma>,
+                                       <4 RK_PA3 1 &pcfg_pull_up_8ma>;
+                       };
+               };
+
+               spdif_in {
+                       spdif_in: spdif-in {
+                               rockchip,pins =
+                                       <0 RK_PC2 1 &pcfg_pull_none>;
+                       };
+               };
+
+               spdif_out {
+                       spdif_out: spdif-out {
+                               rockchip,pins =
+                                       <0 RK_PC1 1 &pcfg_pull_none>;
+                       };
+               };
+
+               spi0 {
+                       spi0_clk: spi0-clk {
+                               rockchip,pins =
+                                       <2 RK_PA2 2 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi0_csn0: spi0-csn0 {
+                               rockchip,pins =
+                                       <2 RK_PA3 2 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi0_miso: spi0-miso {
+                               rockchip,pins =
+                                       <2 RK_PA0 2 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi0_mosi: spi0-mosi {
+                               rockchip,pins =
+                                       <2 RK_PA1 2 &pcfg_pull_up_4ma>;
+                       };
+               };
+
+               spi1 {
+                       spi1_clk: spi1-clk {
+                               rockchip,pins =
+                                       <3 RK_PB3 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_csn0: spi1-csn0 {
+                               rockchip,pins =
+                                       <3 RK_PB5 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_miso: spi1-miso {
+                               rockchip,pins =
+                                       <3 RK_PB2 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_mosi: spi1-mosi {
+                               rockchip,pins =
+                                       <3 RK_PB4 3 &pcfg_pull_up_4ma>;
+                       };
+               };
+
+               spi1-m1 {
+                       spi1m1_miso: spi1m1-miso {
+                               rockchip,pins =
+                                       <2 RK_PA4 2 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1m1_mosi: spi1m1-mosi {
+                               rockchip,pins =
+                                       <2 RK_PA5 2 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1m1_clk: spi1m1-clk {
+                               rockchip,pins =
+                                       <2 RK_PA7 2 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1m1_csn0: spi1m1-csn0 {
+                               rockchip,pins =
+                                       <2 RK_PB1 2 &pcfg_pull_up_4ma>;
+                       };
+               };
+
+               spi2 {
+                       spi2_clk: spi2-clk {
+                               rockchip,pins =
+                                       <1 RK_PD0 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi2_csn0: spi2-csn0 {
+                               rockchip,pins =
+                                       <1 RK_PD1 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi2_miso: spi2-miso {
+                               rockchip,pins =
+                                       <1 RK_PC6 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi2_mosi: spi2-mosi {
+                               rockchip,pins =
+                                       <1 RK_PC7 3 &pcfg_pull_up_4ma>;
+                       };
+               };
+
+               tsadc {
+                       tsadc_otp_gpio: tsadc-otp-gpio {
+                               rockchip,pins =
+                                       <0 RK_PB2 0 &pcfg_pull_none>;
+                       };
+
+                       tsadc_otp_out: tsadc-otp-out {
+                               rockchip,pins =
+                                       <0 RK_PB2 1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart0 {
+                       uart0_xfer: uart0-xfer {
+                               rockchip,pins =
+                                       <2 RK_PA1 1 &pcfg_pull_up>,
+                                       <2 RK_PA0 1 &pcfg_pull_up>;
+                       };
+
+                       uart0_cts: uart0-cts {
+                               rockchip,pins =
+                                       <2 RK_PA2 1 &pcfg_pull_none>;
+                       };
+
+                       uart0_rts: uart0-rts {
+                               rockchip,pins =
+                                       <2 RK_PA3 1 &pcfg_pull_none>;
+                       };
+
+                       uart0_rts_gpio: uart0-rts-gpio {
+                               rockchip,pins =
+                                       <2 RK_PA3 0 &pcfg_pull_none>;
+                       };
+               };
+
+               uart1 {
+                       uart1_xfer: uart1-xfer {
+                               rockchip,pins =
+                                       <1 RK_PD1 1 &pcfg_pull_up>,
+                                       <1 RK_PD0 1 &pcfg_pull_up>;
+                       };
+
+                       uart1_cts: uart1-cts {
+                               rockchip,pins =
+                                       <1 RK_PC6 1 &pcfg_pull_none>;
+                       };
+
+                       uart1_rts: uart1-rts {
+                               rockchip,pins =
+                                       <1 RK_PC7 1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart2-m0 {
+                       uart2m0_xfer: uart2m0-xfer {
+                               rockchip,pins =
+                                       <1 RK_PC7 2 &pcfg_pull_up>,
+                                       <1 RK_PC6 2 &pcfg_pull_up>;
+                       };
+               };
+
+               uart2-m1 {
+                       uart2m1_xfer: uart2m1-xfer {
+                               rockchip,pins =
+                                       <4 RK_PD3 2 &pcfg_pull_up>,
+                                       <4 RK_PD2 2 &pcfg_pull_up>;
+                       };
+               };
+
+               uart3 {
+                       uart3_xfer: uart3-xfer {
+                               rockchip,pins =
+                                       <3 RK_PB5 4 &pcfg_pull_up>,
+                                       <3 RK_PB4 4 &pcfg_pull_up>;
+                       };
+               };
+
+               uart3-m1 {
+                       uart3m1_xfer: uart3m1-xfer {
+                               rockchip,pins =
+                                       <0 RK_PC2 3 &pcfg_pull_up>,
+                                       <0 RK_PC1 3 &pcfg_pull_up>;
+                       };
+               };
+
+               uart4 {
+                       uart4_xfer: uart4-xfer {
+                               rockchip,pins =
+                                       <4 RK_PB1 1 &pcfg_pull_up>,
+                                       <4 RK_PB0 1 &pcfg_pull_up>;
+                       };
+
+                       uart4_cts: uart4-cts {
+                               rockchip,pins =
+                                       <4 RK_PA6 1 &pcfg_pull_none>;
+                       };
+
+                       uart4_rts: uart4-rts {
+                               rockchip,pins =
+                                       <4 RK_PA7 1 &pcfg_pull_none>;
+                       };
+
+                       uart4_rts_gpio: uart4-rts-gpio {
+                               rockchip,pins =
+                                       <4 RK_PA7 0 &pcfg_pull_none>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
new file mode 100644 (file)
index 0000000..76b49f5
--- /dev/null
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+// Copyright (c) 2017-2019 Arm Ltd.
+
+/dts-v1/;
+#include "rk3328.dtsi"
+
+/ {
+       model = "Beelink A1";
+       compatible = "azw,beelink-a1", "rockchip,rk3328";
+
+       /*
+        * UART pins, as viewed with bottom of case removed:
+        *
+        *           Front
+        *        /-------
+        *  L    / o <- Gnd
+        *  e   / o <-- Rx
+        *  f  / o <--- Tx
+        *  t / o <---- +3.3v
+        *    |
+        */
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       gmac_clkin: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "gmac_clkin";
+               #clock-cells = <0>;
+       };
+
+       vcc_host_5v: usb3-current-switch {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb30_host_drv>;
+               regulator-name = "vcc_host_5v";
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_sys: vcc-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       ir-receiver {
+               compatible = "gpio-ir-receiver";
+               gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&analog_sound {
+       simple-audio-card,name = "Analog A/V";
+       status = "okay";
+};
+
+&codec {
+       status = "okay";
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&emmc {
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+       no-sd;
+       no-sdio;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+       vmmc-supply = <&vcc_io>;
+       vqmmc-supply = <&vcc18_emmc>;
+       status = "okay";
+};
+
+&gmac2io {
+       assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
+       assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>;
+       clock_in_out = "input";
+       phy-handle = <&rtl8211f>;
+       phy-mode = "rgmii";
+       phy-supply = <&vcc_io>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmiim1_pins>;
+       snps,aal;
+       snps,pbl = <0x4>;
+       tx_delay = <0x26>;
+       rx_delay = <0x11>;
+       status = "okay";
+
+       mdio {
+               compatible = "snps,dwmac-mdio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               rtl8211f: phy@0 {
+                       reg = <0>;
+                       reset-assert-us = <10000>;
+                       reset-deassert-us = <30000>;
+                       reset-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&gpu {
+       mali-supply = <&vdd_logic>;
+};
+
+&hdmi {
+       status = "okay";
+};
+
+&hdmiphy {
+       status = "okay";
+};
+
+&hdmi_sound {
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <1000000>;
+       i2c-scl-falling-time-ns = <5>;
+       i2c-scl-rising-time-ns = <83>;
+       status = "okay";
+
+       pmic@18 {
+               compatible = "rockchip,rk805";
+               reg = <0x18>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <RK_PA6 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
+               wakeup-source;
+
+               vcc1-supply = <&vcc_sys>;
+               vcc2-supply = <&vcc_sys>;
+               vcc3-supply = <&vcc_sys>;
+               vcc4-supply = <&vcc_sys>;
+               vcc5-supply = <&vcc_io>;
+               vcc6-supply = <&vcc_io>;
+
+               regulators {
+                       vdd_logic: DCDC_REG1 {
+                               regulator-name = "vdd_logic";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vdd_arm: DCDC_REG2 {
+                               regulator-name = "vdd_arm";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <950000>;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-name = "vcc_ddr";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_io: DCDC_REG4 {
+                               regulator-name = "vcc_io";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vdd_18: LDO_REG1 {
+                               regulator-name = "vdd_18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc18_emmc: LDO_REG2 {
+                               regulator-name = "vcc_18emmc";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vdd_11: LDO_REG3 {
+                               regulator-name = "vdd_11";
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1100000>;
+                               };
+                       };
+               };
+       };
+};
+
+&i2s0 {
+       status = "okay";
+};
+
+&i2s1 {
+       status = "okay";
+};
+
+&io_domains {
+       vccio1-supply = <&vcc_io>;
+       vccio2-supply = <&vcc18_emmc>;
+       vccio3-supply = <&vcc_io>;
+       vccio4-supply = <&vdd_18>;
+       vccio5-supply = <&vcc_io>;
+       vccio6-supply = <&vdd_18>;
+       pmuio-supply = <&vcc_io>;
+       status = "okay";
+};
+
+&pinctrl {
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       usb3 {
+               usb30_host_drv: usb30-host-drv {
+                       rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       wifi {
+               bt_dis: bt-dis {
+                       rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               bt_wake_host: bt-wake-host {
+                       rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               chip_en: chip-en {
+                       rockchip,pins = <2 RK_PC3 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               host_wake_bt: host-wake-bt {
+                       rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+
+               wl_dis: wl-dis {
+                       rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               wl_wake_host: wl-wake-host {
+                       rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       disable-wp;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>;
+       vmmc-supply = <&vcc_io>;
+       vqmmc-supply = <&vcc_io>;
+       status = "okay";
+};
+
+&tsadc {
+       rockchip,hw-tshut-mode = <0>;
+       rockchip,hw-tshut-polarity = <0>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&u2phy {
+       status = "okay";
+};
+
+&u2phy_host {
+       status = "okay";
+};
+
+&u2phy_otg {
+       status = "okay";
+};
+
+&usb20_otg {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       pinctrl-names = "default";
+       pinctrl-0 = <&bt_dis &bt_wake_host &chip_en &host_wake_bt &wl_dis &wl_wake_host>;
+       status = "okay";
+};
+
+&vop {
+       status = "okay";
+};
+
+&vop_mmu {
+       status = "okay";
+};
index bb40c16..8d553c9 100644 (file)
@@ -35,6 +35,7 @@
                gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
                pinctrl-names = "default";
                pinctrl-0 = <&sdmmc0m1_gpio>;
+               regulator-boot-on;
                regulator-name = "vcc_sd";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
index 31cc154..91306eb 100644 (file)
                };
        };
 
+       analog_sound: analog-sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,mclk-fs = <256>;
+               simple-audio-card,name = "Analog";
+               status = "disabled";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s1>;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&codec>;
+               };
+       };
+
        arm-pmu {
                compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
                ports = <&vop_out>;
        };
 
+       hdmi_sound: hdmi-sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,mclk-fs = <128>;
+               simple-audio-card,name = "HDMI";
+               status = "disabled";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s0>;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&hdmi>;
+               };
+       };
+
        psci {
                compatible = "arm,psci-1.0", "arm,psci-0.2";
                method = "smc";
index a9f4d6d..9dd3b17 100644 (file)
 
 &spi0 {
        status = "okay";
+
+       cr50@0 {
+               compatible = "google,cr50";
+               reg = <0>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <5 IRQ_TYPE_EDGE_RISING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&h1_int_od_l>;
+               spi-max-frequency = <800000>;
+       };
 };
 
 &pinctrl {
index 50dfab5..4373ed7 100644 (file)
@@ -436,6 +436,16 @@ camera: &i2c7 {
 
 &spi2 {
        status = "okay";
+
+       cr50@0 {
+               compatible = "google,cr50";
+               reg = <0>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <17 IRQ_TYPE_EDGE_RISING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&h1_int_od_l>;
+               spi-max-frequency = <800000>;
+       };
 };
 
 &usb_host0_ohci {
index dd16c80..b788ae4 100644 (file)
        phy-handle = <&rtl8211e>;
        phy-mode = "rgmii";
        phy-supply = <&vcc3v3_s3>;
-       snps,reset-active-low;
-       snps,reset-delays-us = <0 10000 30000>;
-       snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
        tx_delay = <0x28>;
        rx_delay = <0x11>;
        status = "okay";
                        reg = <1>;
                        interrupt-parent = <&gpio3>;
                        interrupts = <RK_PB2 IRQ_TYPE_LEVEL_LOW>;
+                       reset-assert-us = <10000>;
+                       reset-deassert-us = <30000>;
+                       reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
                };
        };
 };
        status = "okay";
 };
 
+&hdmi_sound {
+       status = "okay";
+};
+
 &i2c0 {
        clock-frequency = <400000>;
        i2c-scl-rising-time-ns = <160>;
        status = "okay";
 };
 
+&i2s2 {
+       status = "okay";
+};
+
 &io_domains {
        bt656-supply = <&vcc_1v8>;
        audio-supply = <&vcca1v8_codec>;
index 62ea288..c1edca3 100644 (file)
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
        i2c-scl-rising-time-ns = <168>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts
new file mode 100644 (file)
index 0000000..d6b3042
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd
+ * Copyright (c) 2019 Markus Reichl <m.reichl@fivetechno.de>
+ */
+
+/dts-v1/;
+#include "rk3399-roc-pc.dtsi"
+
+/ {
+       model = "Firefly ROC-RK3399-PC Mezzanine Board";
+       compatible = "firefly,roc-rk3399-pc-mezzanine", "rockchip,rk3399";
+
+       vcc3v3_ngff: vcc3v3-ngff {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_ngff";
+               enable-active-high;
+               gpio = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc3v3_ngff_en>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&dc_12v>;
+       };
+
+       vcc3v3_pcie: vcc3v3-pcie {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_pcie";
+               enable-active-high;
+               gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc3v3_pcie_en>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&dc_12v>;
+       };
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
+&pcie0 {
+       ep-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>;
+       num-lanes = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_perst>;
+       vpcie3v3-supply = <&vcc3v3_pcie>;
+       status = "okay";
+};
+
+&pinctrl {
+       ngff {
+               vcc3v3_ngff_en: vcc3v3-ngff-en {
+                       rockchip,pins = <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pcie {
+               vcc3v3_pcie_en: vcc3v3-pcie-en {
+                       rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pcie_perst: pcie-perst {
+                       rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
index 19f7732..cd41954 100644 (file)
@@ -4,677 +4,9 @@
  */
 
 /dts-v1/;
-#include <dt-bindings/pwm/pwm.h>
-#include "rk3399.dtsi"
-#include "rk3399-opp.dtsi"
+#include "rk3399-roc-pc.dtsi"
 
 / {
        model = "Firefly ROC-RK3399-PC Board";
        compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399";
-
-       chosen {
-               stdout-path = "serial2:1500000n8";
-       };
-
-       backlight: backlight {
-               compatible = "pwm-backlight";
-               pwms = <&pwm0 0 25000 0>;
-       };
-
-       clkin_gmac: external-gmac-clock {
-               compatible = "fixed-clock";
-               clock-frequency = <125000000>;
-               clock-output-names = "clkin_gmac";
-               #clock-cells = <0>;
-       };
-
-       sdio_pwrseq: sdio-pwrseq {
-               compatible = "mmc-pwrseq-simple";
-               clocks = <&rk808 1>;
-               clock-names = "ext_clock";
-               pinctrl-names = "default";
-               pinctrl-0 = <&wifi_enable_h>;
-
-               /*
-                * On the module itself this is one of these (depending
-                * on the actual card populated):
-                * - SDIO_RESET_L_WL_REG_ON
-                * - PDN (power down when low)
-                */
-               reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
-       };
-
-       vcc_vbus_typec0: vcc-vbus-typec0 {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc_vbus_typec0";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-       };
-
-       /*
-        * should be placed inside mp8859, but not until mp8859 has
-        * its own dt-binding.
-        */
-       vcc12v_sys: mp8859-dcdc1 {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc12v_sys";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <12000000>;
-               regulator-max-microvolt = <12000000>;
-               vin-supply = <&vcc_vbus_typec0>;
-       };
-
-       /* switched by pmic_sleep */
-       vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc1v8_s3";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               vin-supply = <&vcc_1v8>;
-       };
-
-       vcc3v3_sys: vcc3v3-sys {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc3v3_sys";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               vin-supply = <&vcc12v_sys>;
-       };
-
-       /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
-       vcc5v0_host: vcc5v0-host-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&vcc5v0_host_en &hub_rst>;
-               regulator-name = "vcc5v0_host";
-               regulator-always-on;
-               vin-supply = <&vcc_sys>;
-       };
-
-       vcc_vbus_typec1: vcc-vbus-typec1 {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&vcc_vbus_typec1_en>;
-               regulator-name = "vcc_vbus_typec1";
-               regulator-always-on;
-               vin-supply = <&vcc_sys>;
-       };
-
-       vcc_sys: vcc-sys {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc_sys";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               vin-supply = <&vcc12v_sys>;
-       };
-
-       vdd_log: vdd-log {
-               compatible = "pwm-regulator";
-               pwms = <&pwm2 0 25000 1>;
-               regulator-name = "vdd_log";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <800000>;
-               regulator-max-microvolt = <1400000>;
-               vin-supply = <&vcc3v3_sys>;
-       };
-};
-
-&cpu_l0 {
-       cpu-supply = <&vdd_cpu_l>;
-};
-
-&cpu_l1 {
-       cpu-supply = <&vdd_cpu_l>;
-};
-
-&cpu_l2 {
-       cpu-supply = <&vdd_cpu_l>;
-};
-
-&cpu_l3 {
-       cpu-supply = <&vdd_cpu_l>;
-};
-
-&cpu_b0 {
-       cpu-supply = <&vdd_cpu_b>;
-};
-
-&cpu_b1 {
-       cpu-supply = <&vdd_cpu_b>;
-};
-
-&emmc_phy {
-       status = "okay";
-};
-
-&gmac {
-       assigned-clocks = <&cru SCLK_RMII_SRC>;
-       assigned-clock-parents = <&clkin_gmac>;
-       clock_in_out = "input";
-       phy-supply = <&vcc_lan>;
-       phy-mode = "rgmii";
-       pinctrl-names = "default";
-       pinctrl-0 = <&rgmii_pins>;
-       snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
-       snps,reset-active-low;
-       snps,reset-delays-us = <0 10000 50000>;
-       tx_delay = <0x28>;
-       rx_delay = <0x11>;
-       status = "okay";
-};
-
-&hdmi {
-       ddc-i2c-bus = <&i2c3>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&hdmi_cec>;
-       status = "okay";
-};
-
-&i2c0 {
-       clock-frequency = <400000>;
-       i2c-scl-rising-time-ns = <168>;
-       i2c-scl-falling-time-ns = <4>;
-       status = "okay";
-
-       rk808: pmic@1b {
-               compatible = "rockchip,rk808";
-               reg = <0x1b>;
-               interrupt-parent = <&gpio1>;
-               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
-               #clock-cells = <1>;
-               clock-output-names = "xin32k", "rk808-clkout2";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pmic_int_l>;
-               rockchip,system-power-controller;
-               wakeup-source;
-
-               vcc1-supply = <&vcc3v3_sys>;
-               vcc2-supply = <&vcc3v3_sys>;
-               vcc3-supply = <&vcc3v3_sys>;
-               vcc4-supply = <&vcc3v3_sys>;
-               vcc6-supply = <&vcc3v3_sys>;
-               vcc7-supply = <&vcc3v3_sys>;
-               vcc8-supply = <&vcc3v3_sys>;
-               vcc9-supply = <&vcc3v3_sys>;
-               vcc10-supply = <&vcc3v3_sys>;
-               vcc11-supply = <&vcc3v3_sys>;
-               vcc12-supply = <&vcc3v3_sys>;
-               vddio-supply = <&vcc1v8_pmu>;
-
-               regulators {
-                       vdd_center: DCDC_REG1 {
-                               regulator-name = "vdd_center";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <750000>;
-                               regulator-max-microvolt = <1350000>;
-                               regulator-ramp-delay = <6001>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vdd_cpu_l: DCDC_REG2 {
-                               regulator-name = "vdd_cpu_l";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <750000>;
-                               regulator-max-microvolt = <1350000>;
-                               regulator-ramp-delay = <6001>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcc_ddr: DCDC_REG3 {
-                               regulator-name = "vcc_ddr";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                               };
-                       };
-
-                       vcc_1v8: DCDC_REG4 {
-                               regulator-name = "vcc_1v8";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcca1v8_codec: LDO_REG1 {
-                               regulator-name = "vcca1v8_codec";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcc1v8_hdmi: LDO_REG2 {
-                               regulator-name = "vcc1v8_hdmi";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcc1v8_pmu: LDO_REG3 {
-                               regulator-name = "vcc1v8_pmu";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcc_sdio: LDO_REG4 {
-                               regulator-name = "vcc_sdio";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3000000>;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3000000>;
-                               };
-                       };
-
-                       vcca3v0_codec: LDO_REG5 {
-                               regulator-name = "vcca3v0_codec";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <3000000>;
-                               regulator-max-microvolt = <3000000>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcc_1v5: LDO_REG6 {
-                               regulator-name = "vcc_1v5";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1500000>;
-                               regulator-max-microvolt = <1500000>;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1500000>;
-                               };
-                       };
-
-                       vcca0v9_hdmi: LDO_REG7 {
-                               regulator-name = "vcca0v9_hdmi";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <900000>;
-                               regulator-max-microvolt = <900000>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcc_3v0: LDO_REG8 {
-                               regulator-name = "vcc_3v0";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <3000000>;
-                               regulator-max-microvolt = <3000000>;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3000000>;
-                               };
-                       };
-
-                       vcc3v3_s3: vcc_lan: SWITCH_REG1 {
-                               regulator-name = "vcc3v3_s3";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcc3v3_s0: SWITCH_REG2 {
-                               regulator-name = "vcc3v3_s0";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-               };
-       };
-
-       vdd_cpu_b: regulator@40 {
-               compatible = "silergy,syr827";
-               reg = <0x40>;
-               fcs,suspend-voltage-selector = <1>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&vsel1_gpio>;
-               regulator-name = "vdd_cpu_b";
-               regulator-min-microvolt = <712500>;
-               regulator-max-microvolt = <1500000>;
-               regulator-ramp-delay = <1000>;
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc3v3_sys>;
-
-               regulator-state-mem {
-                       regulator-off-in-suspend;
-               };
-       };
-
-       vdd_gpu: regulator@41 {
-               compatible = "silergy,syr828";
-               reg = <0x41>;
-               fcs,suspend-voltage-selector = <1>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&vsel2_gpio>;
-               regulator-name = "vdd_gpu";
-               regulator-min-microvolt = <712500>;
-               regulator-max-microvolt = <1500000>;
-               regulator-ramp-delay = <1000>;
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc3v3_sys>;
-
-               regulator-state-mem {
-                       regulator-off-in-suspend;
-               };
-       };
-};
-
-&i2c1 {
-       i2c-scl-rising-time-ns = <300>;
-       i2c-scl-falling-time-ns = <15>;
-       status = "okay";
-};
-
-&i2c3 {
-       i2c-scl-rising-time-ns = <450>;
-       i2c-scl-falling-time-ns = <15>;
-       status = "okay";
-};
-
-&i2c4 {
-       i2c-scl-rising-time-ns = <600>;
-       i2c-scl-falling-time-ns = <20>;
-       status = "okay";
-
-       fusb1: usb-typec@22 {
-               compatible = "fcs,fusb302";
-               reg = <0x22>;
-               interrupt-parent = <&gpio1>;
-               interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&fusb1_int>;
-               vbus-supply = <&vcc_vbus_typec1>;
-               status = "okay";
-       };
-};
-
-&i2c7 {
-       i2c-scl-rising-time-ns = <600>;
-       i2c-scl-falling-time-ns = <20>;
-       status = "okay";
-
-       fusb0: usb-typec@22 {
-               compatible = "fcs,fusb302";
-               reg = <0x22>;
-               interrupt-parent = <&gpio1>;
-               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&fusb0_int>;
-               vbus-supply = <&vcc_vbus_typec0>;
-               status = "okay";
-       };
-};
-
-&i2s0 {
-       rockchip,playback-channels = <8>;
-       rockchip,capture-channels = <8>;
-       status = "okay";
-};
-
-&i2s1 {
-       rockchip,playback-channels = <2>;
-       rockchip,capture-channels = <2>;
-       status = "okay";
-};
-
-&i2s2 {
-       status = "okay";
-};
-
-&io_domains {
-       audio-supply = <&vcca1v8_codec>;
-       bt656-supply = <&vcc_3v0>;
-       gpio1830-supply = <&vcc_3v0>;
-       sdmmc-supply = <&vcc_sdio>;
-       status = "okay";
-};
-
-&pmu_io_domains {
-       pmu1830-supply = <&vcc_3v0>;
-       status = "okay";
-};
-
-&pinctrl {
-       lcd-panel {
-               lcd_panel_reset: lcd-panel-reset {
-                       rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-
-       pmic {
-               vsel1_gpio: vsel1-gpio {
-                       rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
-               };
-
-               vsel2_gpio: vsel2-gpio {
-                       rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
-               };
-       };
-
-       sdio-pwrseq {
-               wifi_enable_h: wifi-enable-h {
-                       rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
-       pmic {
-               pmic_int_l: pmic-int-l {
-                       rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-
-       usb2 {
-               vcc5v0_host_en: vcc5v0-host-en {
-                       rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               hub_rst: hub-rst {
-                       rockchip,pins = <2 RK_PA4 RK_FUNC_GPIO &pcfg_output_high>;
-               };
-       };
-
-       usb-typec {
-               vcc_vbus_typec1_en: vcc-vbus-typec1-en {
-                       rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
-       fusb30x {
-               fusb0_int: fusb0-int {
-                       rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-
-               fusb1_int: fusb1-int {
-                       rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-};
-
-&pwm0 {
-       status = "okay";
-};
-
-&pwm2 {
-       status = "okay";
-};
-
-&saradc {
-       vref-supply = <&vcca1v8_s3>;
-       status = "okay";
-};
-
-&sdmmc {
-       bus-width = <4>;
-       cap-mmc-highspeed;
-       cap-sd-highspeed;
-       cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
-       disable-wp;
-       max-frequency = <150000000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
-       status = "okay";
-};
-
-&sdhci {
-       bus-width = <8>;
-       mmc-hs400-1_8v;
-       mmc-hs400-enhanced-strobe;
-       non-removable;
-       status = "okay";
-};
-
-&tcphy0 {
-       status = "okay";
-};
-
-&tcphy1 {
-       status = "okay";
-};
-
-&tsadc {
-       /* tshut mode 0:CRU 1:GPIO */
-       rockchip,hw-tshut-mode = <1>;
-       /* tshut polarity 0:LOW 1:HIGH */
-       rockchip,hw-tshut-polarity = <1>;
-       status = "okay";
-};
-
-&u2phy0 {
-       status = "okay";
-
-       u2phy0_otg: otg-port {
-               phy-supply = <&vcc_vbus_typec0>;
-               status = "okay";
-       };
-
-       u2phy0_host: host-port {
-               phy-supply = <&vcc5v0_host>;
-               status = "okay";
-       };
-};
-
-&u2phy1 {
-       status = "okay";
-
-       u2phy1_otg: otg-port {
-               phy-supply = <&vcc_vbus_typec1>;
-               status = "okay";
-       };
-
-       u2phy1_host: host-port {
-               phy-supply = <&vcc5v0_host>;
-               status = "okay";
-       };
-};
-
-&uart0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart0_xfer &uart0_cts>;
-       status = "okay";
-};
-
-&uart2 {
-       status = "okay";
-};
-
-&usb_host0_ehci {
-       status = "okay";
-};
-
-&usb_host0_ohci {
-       status = "okay";
-};
-
-&usb_host1_ehci {
-       status = "okay";
-};
-
-&usb_host1_ohci {
-       status = "okay";
-};
-
-&usbdrd3_0 {
-       status = "okay";
-};
-
-&usbdrd_dwc3_0 {
-       status = "okay";
-};
-
-&usbdrd3_1 {
-       status = "okay";
-};
-
-&usbdrd_dwc3_1 {
-       status = "okay";
-       dr_mode = "host";
-};
-
-&vopb {
-       status = "okay";
-};
-
-&vopb_mmu {
-       status = "okay";
-};
-
-&vopl {
-       status = "okay";
-};
-
-&vopl_mmu {
-       status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
new file mode 100644 (file)
index 0000000..7e07dae
--- /dev/null
@@ -0,0 +1,767 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+       model = "Firefly ROC-RK3399-PC Board";
+       compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399";
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm0 0 25000 0>;
+       };
+
+       clkin_gmac: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "clkin_gmac";
+               #clock-cells = <0>;
+       };
+
+       adc-keys {
+               compatible = "adc-keys";
+               io-channels = <&saradc 1>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1500000>;
+               poll-interval = <100>;
+
+               recovery {
+                       label = "Recovery";
+                       linux,code = <KEY_VENDOR>;
+                       press-threshold-microvolt = <18000>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               autorepeat;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwr_key_l>;
+
+               power {
+                       debounce-interval = <100>;
+                       gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+                       label = "GPIO Key Power";
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&work_led_gpio>, <&diy_led_gpio>, <&yellow_led_gpio>;
+
+               work-led {
+                       label = "green:work";
+                       gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               diy-led {
+                       label = "red:diy";
+                       gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+                       linux,default-trigger = "mmc1";
+               };
+
+               yellow-led {
+                       label = "yellow:yellow-led";
+                       gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+                       linux,default-trigger = "mmc0";
+               };
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rk808 1>;
+               clock-names = "ext_clock";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_enable_h>;
+
+               /*
+                * On the module itself this is one of these (depending
+                * on the actual card populated):
+                * - SDIO_RESET_L_WL_REG_ON
+                * - PDN (power down when low)
+                */
+               reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+       };
+
+       vcc_vbus_typec0: vcc-vbus-typec0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_vbus_typec0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       /*
+        * should be placed inside mp8859, but not until mp8859 has
+        * its own dt-binding.
+        */
+       dc_12v: mp8859-dcdc1 {
+               compatible = "regulator-fixed";
+               regulator-name = "dc_12v";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               vin-supply = <&vcc_vbus_typec0>;
+       };
+
+       /* switched by pmic_sleep */
+       vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc1v8_s3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_1v8>;
+       };
+
+       vcc3v3_sys: vcc3v3-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&dc_12v>;
+       };
+
+       /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host_en &hub_rst>;
+               regulator-name = "vcc5v0_host";
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_vbus_typec1: vcc-vbus-typec1 {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc_vbus_typec1_en>;
+               regulator-name = "vcc_vbus_typec1";
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_sys: vcc-sys {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio2 RK_PA6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc_sys_en>;
+               regulator-name = "vcc_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&dc_12v>;
+       };
+
+       vdd_log: vdd-log {
+               compatible = "pwm-regulator";
+               pwms = <&pwm2 0 25000 1>;
+               regulator-name = "vdd_log";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1400000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+};
+
+&cpu_l0 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l1 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l2 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l3 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_b0 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&cpu_b1 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&emmc_phy {
+       status = "okay";
+};
+
+&gmac {
+       assigned-clocks = <&cru SCLK_RMII_SRC>;
+       assigned-clock-parents = <&clkin_gmac>;
+       clock_in_out = "input";
+       phy-supply = <&vcc_lan>;
+       phy-mode = "rgmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+       snps,reset-active-low;
+       snps,reset-delays-us = <0 10000 50000>;
+       tx_delay = <0x28>;
+       rx_delay = <0x11>;
+       status = "okay";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_cec>;
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       i2c-scl-rising-time-ns = <168>;
+       i2c-scl-falling-time-ns = <4>;
+       status = "okay";
+
+       rk808: pmic@1b {
+               compatible = "rockchip,rk808";
+               reg = <0x1b>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+               #clock-cells = <1>;
+               clock-output-names = "xin32k", "rk808-clkout2";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
+               wakeup-source;
+
+               vcc1-supply = <&vcc3v3_sys>;
+               vcc2-supply = <&vcc3v3_sys>;
+               vcc3-supply = <&vcc3v3_sys>;
+               vcc4-supply = <&vcc3v3_sys>;
+               vcc6-supply = <&vcc3v3_sys>;
+               vcc7-supply = <&vcc3v3_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc3v3_sys>;
+               vcc10-supply = <&vcc3v3_sys>;
+               vcc11-supply = <&vcc3v3_sys>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vcc13-supply = <&vcc3v3_sys>;
+               vcc14-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcc_3v0>;
+
+               regulators {
+                       vdd_center: DCDC_REG1 {
+                               regulator-name = "vdd_center";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_l: DCDC_REG2 {
+                               regulator-name = "vdd_cpu_l";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-name = "vcc_ddr";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8: DCDC_REG4 {
+                               regulator-name = "vcc_1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcca1v8_codec: LDO_REG1 {
+                               regulator-name = "vcca1v8_codec";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc1v8_hdmi: LDO_REG2 {
+                               regulator-name = "vcc1v8_hdmi";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc1v8_pmu: LDO_REG3 {
+                               regulator-name = "vcc1v8_pmu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc_sdio: LDO_REG4 {
+                               regulator-name = "vcc_sdio";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcca3v0_codec: LDO_REG5 {
+                               regulator-name = "vcca3v0_codec";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v5: LDO_REG6 {
+                               regulator-name = "vcc_1v5";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1500000>;
+                               };
+                       };
+
+                       vcca0v9_hdmi: LDO_REG7 {
+                               regulator-name = "vcca0v9_hdmi";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_3v0: LDO_REG8 {
+                               regulator-name = "vcc_3v0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc3v3_s3: vcc_lan: SWITCH_REG1 {
+                               regulator-name = "vcc3v3_s3";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_s0: SWITCH_REG2 {
+                               regulator-name = "vcc3v3_s0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+
+       vdd_cpu_b: regulator@40 {
+               compatible = "silergy,syr827";
+               reg = <0x40>;
+               fcs,suspend-voltage-selector = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vsel1_gpio>;
+               regulator-name = "vdd_cpu_b";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc3v3_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_gpu: regulator@41 {
+               compatible = "silergy,syr828";
+               reg = <0x41>;
+               fcs,suspend-voltage-selector = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vsel2_gpio>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc3v3_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&i2c1 {
+       i2c-scl-rising-time-ns = <300>;
+       i2c-scl-falling-time-ns = <15>;
+       status = "okay";
+};
+
+&i2c3 {
+       i2c-scl-rising-time-ns = <450>;
+       i2c-scl-falling-time-ns = <15>;
+       status = "okay";
+};
+
+&i2c4 {
+       i2c-scl-rising-time-ns = <600>;
+       i2c-scl-falling-time-ns = <20>;
+       status = "okay";
+
+       fusb1: usb-typec@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&fusb1_int>;
+               vbus-supply = <&vcc_vbus_typec1>;
+               status = "okay";
+       };
+};
+
+&i2c7 {
+       i2c-scl-rising-time-ns = <600>;
+       i2c-scl-falling-time-ns = <20>;
+       status = "okay";
+
+       fusb0: usb-typec@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&fusb0_int>;
+               vbus-supply = <&vcc_vbus_typec0>;
+               status = "okay";
+       };
+};
+
+&i2s0 {
+       rockchip,playback-channels = <8>;
+       rockchip,capture-channels = <8>;
+       status = "okay";
+};
+
+&i2s1 {
+       rockchip,playback-channels = <2>;
+       rockchip,capture-channels = <2>;
+       status = "okay";
+};
+
+&i2s2 {
+       status = "okay";
+};
+
+&io_domains {
+       audio-supply = <&vcca1v8_codec>;
+       bt656-supply = <&vcc_3v0>;
+       gpio1830-supply = <&vcc_3v0>;
+       sdmmc-supply = <&vcc_sdio>;
+       status = "okay";
+};
+
+&pmu_io_domains {
+       pmu1830-supply = <&vcc_3v0>;
+       status = "okay";
+};
+
+&pinctrl {
+       buttons {
+               pwr_key_l: pwr-key-l {
+                       rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       lcd-panel {
+               lcd_panel_reset: lcd-panel-reset {
+                       rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       leds {
+               diy_led_gpio: diy_led-gpio {
+                       rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               work_led_gpio: work_led-gpio {
+                       rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               yellow_led_gpio: yellow_led-gpio {
+                       rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               vsel1_gpio: vsel1-gpio {
+                       rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               vsel2_gpio: vsel2-gpio {
+                       rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       sdio-pwrseq {
+               wifi_enable_h: wifi-enable-h {
+                       rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       usb2 {
+               vcc5v0_host_en: vcc5v0-host-en {
+                       rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               vcc_sys_en: vcc-sys-en {
+                       rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               hub_rst: hub-rst {
+                       rockchip,pins = <2 RK_PA4 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+       };
+
+       usb-typec {
+               vcc_vbus_typec1_en: vcc-vbus-typec1-en {
+                       rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       fusb30x {
+               fusb0_int: fusb0-int {
+                       rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               fusb1_int: fusb1-int {
+                       rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcca1v8_s3>;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       max-frequency = <150000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       non-removable;
+       status = "okay";
+};
+
+&tcphy0 {
+       status = "okay";
+};
+
+&tcphy1 {
+       status = "okay";
+};
+
+&tsadc {
+       /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-mode = <1>;
+       /* tshut polarity 0:LOW 1:HIGH */
+       rockchip,hw-tshut-polarity = <1>;
+       status = "okay";
+};
+
+&u2phy0 {
+       status = "okay";
+
+       u2phy0_otg: otg-port {
+               phy-supply = <&vcc_vbus_typec0>;
+               status = "okay";
+       };
+
+       u2phy0_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&u2phy1 {
+       status = "okay";
+
+       u2phy1_otg: otg-port {
+               phy-supply = <&vcc_vbus_typec1>;
+               status = "okay";
+       };
+
+       u2phy1_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usbdrd3_0 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+       status = "okay";
+};
+
+&usbdrd3_1 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
index 1ae1ebd..188d9df 100644 (file)
 
        sdio0 {
                sdio0_bus4: sdio0-bus4 {
-                       rockchip,pins =
-                               <2 20 RK_FUNC_1 &pcfg_pull_up_20ma>,
-                               <2 21 RK_FUNC_1 &pcfg_pull_up_20ma>,
-                               <2 22 RK_FUNC_1 &pcfg_pull_up_20ma>,
-                               <2 23 RK_FUNC_1 &pcfg_pull_up_20ma>;
+                       rockchip,pins = <2 RK_PC4 1 &pcfg_pull_up_20ma>,
+                                       <2 RK_PC5 1 &pcfg_pull_up_20ma>,
+                                       <2 RK_PC6 1 &pcfg_pull_up_20ma>,
+                                       <2 RK_PC7 1 &pcfg_pull_up_20ma>;
                };
 
                sdio0_cmd: sdio0-cmd {
-                       rockchip,pins =
-                               <2 24 RK_FUNC_1 &pcfg_pull_up_20ma>;
+                       rockchip,pins = <2 RK_PD0 1 &pcfg_pull_up_20ma>;
                };
 
                sdio0_clk: sdio0-clk {
-                       rockchip,pins =
-                               <2 25 RK_FUNC_1 &pcfg_pull_none_20ma>;
+                       rockchip,pins = <2 RK_PD1 1 &pcfg_pull_none_20ma>;
                };
        };
 
 
        wifi {
                wifi_enable_h: wifi-enable-h {
-                       rockchip,pins =
-                               <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+                       rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
                };
 
                wifi_host_wake_l: wifi-host-wake-l {
index e544deb..7f4b2eb 100644 (file)
                reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
        };
 
+       sound {
+               compatible = "audio-graph-card";
+               label = "rockchip,rk3399";
+               dais = <&i2s1_p0>;
+       };
+
        vcc12v_dcin: vcc12v-dcin {
                compatible = "regulator-fixed";
                regulator-name = "vcc12v_dcin";
        i2c-scl-rising-time-ns = <300>;
        i2c-scl-falling-time-ns = <15>;
        status = "okay";
+
+       es8316: codec@11 {
+               compatible = "everest,es8316";
+               reg = <0x11>;
+               clocks = <&cru SCLK_I2S_8CH_OUT>;
+               clock-names = "mclk";
+               #sound-dai-cells = <0>;
+
+               port {
+                       es8316_p0_0: endpoint {
+                               remote-endpoint = <&i2s1_p0_0>;
+                       };
+               };
+       };
 };
 
 &i2c3 {
        rockchip,playback-channels = <2>;
        rockchip,capture-channels = <2>;
        status = "okay";
+
+       i2s1_p0: port {
+               i2s1_p0_0: endpoint {
+                       dai-format = "i2s";
+                       mclk-fs = <256>;
+                       remote-endpoint = <&es8316_p0_0>;
+               };
+       };
 };
 
 &i2s2 {
index cede1ad..e62ea0e 100644 (file)
                its: interrupt-controller@fee20000 {
                        compatible = "arm,gic-v3-its";
                        msi-controller;
+                       #msi-cells = <1>;
                        reg = <0x0 0xfee20000 0x0 0x20000>;
                };
 
index 799c75f..efb2457 100644 (file)
                        reg = <0x00 0x30e00000 0x00 0x1000>;
                        #hwlock-cells = <1>;
                };
+
+               mailbox0_cluster0: mailbox@31f80000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f80000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster1: mailbox@31f81000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f81000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster2: mailbox@31f82000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f82000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster3: mailbox@31f83000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f83000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster4: mailbox@31f84000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f84000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster5: mailbox@31f85000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f85000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster6: mailbox@31f86000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f86000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster7: mailbox@31f87000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f87000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster8: mailbox@31f88000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f88000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster9: mailbox@31f89000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f89000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster10: mailbox@31f8a000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f8a000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
+
+               mailbox0_cluster11: mailbox@31f8b000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f8b000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&intr_main_navss>;
+               };
        };
 
        main_gpio0:  main_gpio0@600000 {
index 1102b84..8a85b48 100644 (file)
        bus-width = <8>;
        non-removable;
        ti,driver-strength-ohm = <50>;
+       disable-wp;
 };
 
 &dwc3_1 {
 &pcie1_ep {
        status = "disabled";
 };
+
+&mailbox0_cluster0 {
+       interrupts = <164 0>;
+
+       mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
+               ti,mbox-tx = <1 0 0>;
+               ti,mbox-rx = <0 0 0>;
+       };
+};
+
+&mailbox0_cluster1 {
+       interrupts = <165 0>;
+
+       mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
+               ti,mbox-tx = <1 0 0>;
+               ti,mbox-rx = <0 0 0>;
+       };
+};
+
+&mailbox0_cluster2 {
+       status = "disabled";
+};
+
+&mailbox0_cluster3 {
+       status = "disabled";
+};
+
+&mailbox0_cluster4 {
+       status = "disabled";
+};
+
+&mailbox0_cluster5 {
+       status = "disabled";
+};
+
+&mailbox0_cluster6 {
+       status = "disabled";
+};
+
+&mailbox0_cluster7 {
+       status = "disabled";
+};
+
+&mailbox0_cluster8 {
+       status = "disabled";
+};
+
+&mailbox0_cluster9 {
+       status = "disabled";
+};
+
+&mailbox0_cluster10 {
+       status = "disabled";
+};
+
+&mailbox0_cluster11 {
+       status = "disabled";
+};
index d2894d5..2a3cd61 100644 (file)
                        J721E_IOPAD(0x0, PIN_INPUT, 7) /* (AC18) EXTINTn.GPIO0_0 */
                >;
        };
+
+       main_mmc1_pins_default: main_mmc1_pins_default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x254, PIN_INPUT, 0) /* (R29) MMC1_CMD */
+                       J721E_IOPAD(0x250, PIN_INPUT, 0) /* (P25) MMC1_CLK */
+                       J721E_IOPAD(0x2ac, PIN_INPUT, 0) /* (P25) MMC1_CLKLB */
+                       J721E_IOPAD(0x24c, PIN_INPUT, 0) /* (R24) MMC1_DAT0 */
+                       J721E_IOPAD(0x248, PIN_INPUT, 0) /* (P24) MMC1_DAT1 */
+                       J721E_IOPAD(0x244, PIN_INPUT, 0) /* (R25) MMC1_DAT2 */
+                       J721E_IOPAD(0x240, PIN_INPUT, 0) /* (R26) MMC1_DAT3 */
+                       J721E_IOPAD(0x258, PIN_INPUT, 0) /* (P23) MMC1_SDCD */
+                       J721E_IOPAD(0x25c, PIN_INPUT, 0) /* (R28) MMC1_SDWP */
+               >;
+       };
+
+       main_usbss0_pins_default: main_usbss0_pins_default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x290, PIN_OUTPUT, 0) /* (U6) USB0_DRVVBUS */
+               >;
+       };
+
+       main_usbss1_pins_default: main_usbss1_pins_default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
+               >;
+       };
 };
 
 &wkup_pmx0 {
 &wkup_gpio1 {
        status = "disabled";
 };
+
+&mailbox0_cluster0 {
+       interrupts = <214 0>;
+
+       mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
+               ti,mbox-rx = <0 0 0>;
+               ti,mbox-tx = <1 0 0>;
+       };
+
+       mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
+               ti,mbox-rx = <2 0 0>;
+               ti,mbox-tx = <3 0 0>;
+       };
+};
+
+&mailbox0_cluster1 {
+       interrupts = <215 0>;
+
+       mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+               ti,mbox-rx = <0 0 0>;
+               ti,mbox-tx = <1 0 0>;
+       };
+
+       mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+               ti,mbox-rx = <2 0 0>;
+               ti,mbox-tx = <3 0 0>;
+       };
+};
+
+&mailbox0_cluster2 {
+       interrupts = <216 0>;
+
+       mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+               ti,mbox-rx = <0 0 0>;
+               ti,mbox-tx = <1 0 0>;
+       };
+
+       mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+               ti,mbox-rx = <2 0 0>;
+               ti,mbox-tx = <3 0 0>;
+       };
+};
+
+&mailbox0_cluster3 {
+       interrupts = <217 0>;
+
+       mbox_c66_0: mbox-c66-0 {
+               ti,mbox-rx = <0 0 0>;
+               ti,mbox-tx = <1 0 0>;
+       };
+
+       mbox_c66_1: mbox-c66-1 {
+               ti,mbox-rx = <2 0 0>;
+               ti,mbox-tx = <3 0 0>;
+       };
+};
+
+&mailbox0_cluster4 {
+       interrupts = <218 0>;
+
+       mbox_c71_0: mbox-c71-0 {
+               ti,mbox-rx = <0 0 0>;
+               ti,mbox-tx = <1 0 0>;
+       };
+};
+
+&mailbox0_cluster5 {
+       status = "disabled";
+};
+
+&mailbox0_cluster6 {
+       status = "disabled";
+};
+
+&mailbox0_cluster7 {
+       status = "disabled";
+};
+
+&mailbox0_cluster8 {
+       status = "disabled";
+};
+
+&mailbox0_cluster9 {
+       status = "disabled";
+};
+
+&mailbox0_cluster10 {
+       status = "disabled";
+};
+
+&mailbox0_cluster11 {
+       status = "disabled";
+};
+
+&main_sdhci0 {
+       /* eMMC */
+       non-removable;
+       ti,driver-strength-ohm = <50>;
+       disable-wp;
+};
+
+&main_sdhci1 {
+       /* SD/MMC */
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_mmc1_pins_default>;
+       ti,driver-strength-ohm = <50>;
+       disable-wp;
+};
+
+&main_sdhci2 {
+       /* Unused */
+       status = "disabled";
+};
+
+&usbss0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_usbss0_pins_default>;
+       ti,usb2-only;
+       ti,vbus-divider;
+};
+
+&usb0 {
+       dr_mode = "otg";
+       maximum-speed = "high-speed";
+};
+
+&usbss1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_usbss1_pins_default>;
+       ti,usb2-only;
+};
+
+&usb1 {
+       dr_mode = "host";
+       maximum-speed = "high-speed";
+};
index 698ef9a..1e4c2b7 100644 (file)
                        reg = <0x00 0x30e00000 0x00 0x1000>;
                        #hwlock-cells = <1>;
                };
+
+               mailbox0_cluster0: mailbox@31f80000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f80000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster1: mailbox@31f81000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f81000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster2: mailbox@31f82000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f82000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster3: mailbox@31f83000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f83000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster4: mailbox@31f84000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f84000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster5: mailbox@31f85000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f85000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster6: mailbox@31f86000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f86000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster7: mailbox@31f87000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f87000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster8: mailbox@31f88000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f88000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster9: mailbox@31f89000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f89000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster10: mailbox@31f8a000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f8a000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
+
+               mailbox0_cluster11: mailbox@31f8b000 {
+                       compatible = "ti,am654-mailbox";
+                       reg = <0x00 0x31f8b000 0x00 0x200>;
+                       #mbox-cells = <1>;
+                       ti,mbox-num-users = <4>;
+                       ti,mbox-num-fifos = <16>;
+                       interrupt-parent = <&main_navss_intr>;
+               };
        };
 
        secure_proxy_main: mailbox@32c00000 {
                clocks = <&k3_clks 112 0>;
                clock-names = "gpio";
        };
+
+       main_sdhci0: sdhci@4f80000 {
+               compatible = "ti,j721e-sdhci-8bit";
+               reg = <0x0 0x4f80000 0x0 0x1000>, <0x0 0x4f88000 0x0 0x400>;
+               interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+               power-domains = <&k3_pds 91 TI_SCI_PD_EXCLUSIVE>;
+               clock-names = "clk_xin", "clk_ahb";
+               clocks = <&k3_clks 91 1>, <&k3_clks 91 0>;
+               assigned-clocks = <&k3_clks 91 1>;
+               assigned-clock-parents = <&k3_clks 91 2>;
+               bus-width = <8>;
+               mmc-hs400-1_8v;
+               mmc-ddr-1_8v;
+               ti,otap-del-sel = <0x2>;
+               ti,trm-icp = <0x8>;
+               ti,strobe-sel = <0x77>;
+               dma-coherent;
+       };
+
+       main_sdhci1: sdhci@4fb0000 {
+               compatible = "ti,j721e-sdhci-4bit";
+               reg = <0x0 0x04fb0000 0x0 0x1000>, <0x0 0x4fb8000 0x0 0x400>;
+               interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+               power-domains = <&k3_pds 92 TI_SCI_PD_EXCLUSIVE>;
+               clock-names = "clk_xin", "clk_ahb";
+               clocks = <&k3_clks 92 0>, <&k3_clks 92 5>;
+               assigned-clocks = <&k3_clks 92 0>;
+               assigned-clock-parents = <&k3_clks 92 1>;
+               ti,otap-del-sel = <0x2>;
+               ti,trm-icp = <0x8>;
+               ti,clkbuf-sel = <0x7>;
+               dma-coherent;
+               no-1-8-v;
+       };
+
+       main_sdhci2: sdhci@4f98000 {
+               compatible = "ti,j721e-sdhci-4bit";
+               reg = <0x0 0x4f98000 0x0 0x1000>, <0x0 0x4f90000 0x0 0x400>;
+               interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+               power-domains = <&k3_pds 93 TI_SCI_PD_EXCLUSIVE>;
+               clock-names = "clk_xin", "clk_ahb";
+               clocks = <&k3_clks 93 0>, <&k3_clks 93 5>;
+               assigned-clocks = <&k3_clks 93 0>;
+               assigned-clock-parents = <&k3_clks 93 1>;
+               ti,otap-del-sel = <0x2>;
+               ti,trm-icp = <0x8>;
+               ti,clkbuf-sel = <0x7>;
+               dma-coherent;
+               no-1-8-v;
+       };
+
+       usbss0: cdns_usb@4104000 {
+               compatible = "ti,j721e-usb";
+               reg = <0x00 0x4104000 0x00 0x100>;
+               dma-coherent;
+               power-domains = <&k3_pds 288 TI_SCI_PD_EXCLUSIVE>;
+               clocks = <&k3_clks 288 15>, <&k3_clks 288 3>;
+               clock-names = "ref", "lpm";
+               assigned-clocks = <&k3_clks 288 15>;    /* USB2_REFCLK */
+               assigned-clock-parents = <&k3_clks 288 16>; /* HFOSC0 */
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               usb0: usb@6000000 {
+                       compatible = "cdns,usb3";
+                       reg = <0x00 0x6000000 0x00 0x10000>,
+                             <0x00 0x6010000 0x00 0x10000>,
+                             <0x00 0x6020000 0x00 0x10000>;
+                       reg-names = "otg", "xhci", "dev";
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,  /* irq.0 */
+                                    <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, /* irq.6 */
+                                    <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; /* otgirq.0 */
+                       interrupt-names = "host",
+                                         "peripheral",
+                                         "otg";
+                       maximum-speed = "super-speed";
+                       dr_mode = "otg";
+               };
+       };
+
+       usbss1: cdns_usb@4114000 {
+               compatible = "ti,j721e-usb";
+               reg = <0x00 0x4114000 0x00 0x100>;
+               dma-coherent;
+               power-domains = <&k3_pds 289 TI_SCI_PD_EXCLUSIVE>;
+               clocks = <&k3_clks 289 15>, <&k3_clks 289 3>;
+               clock-names = "ref", "lpm";
+               assigned-clocks = <&k3_clks 289 15>;    /* USB2_REFCLK */
+               assigned-clock-parents = <&k3_clks 289 16>; /* HFOSC0 */
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               usb1: usb@6400000 {
+                       compatible = "cdns,usb3";
+                       reg = <0x00 0x6400000 0x00 0x10000>,
+                             <0x00 0x6410000 0x00 0x10000>,
+                             <0x00 0x6420000 0x00 0x10000>;
+                       reg-names = "otg", "xhci", "dev";
+                       interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+                                    <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, /* irq.6 */
+                                    <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; /* otgirq.0 */
+                       interrupt-names = "host",
+                                         "peripheral",
+                                         "otg";
+                       maximum-speed = "super-speed";
+                       dr_mode = "otg";
+               };
+       };
 };
index 43ea1ba..ee5470e 100644 (file)
                         <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
                         <0x00 0x00900000 0x00 0x00900000 0x00 0x00012000>, /* serdes */
                         <0x00 0x00A40000 0x00 0x00A40000 0x00 0x00000800>, /* timesync router */
+                        <0x00 0x06000000 0x00 0x06000000 0x00 0x00400000>, /* USBSS0 */
+                        <0x00 0x06400000 0x00 0x06400000 0x00 0x00400000>, /* USBSS1 */
                         <0x00 0x01000000 0x00 0x01000000 0x00 0x0af02400>, /* Most peripherals */
                         <0x00 0x30800000 0x00 0x30800000 0x00 0x0bc00000>, /* MAIN NAVSS */
                         <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01000000>, /* PCIe Core*/
index 9aa6734..3c731e7 100644 (file)
                method = "smc";
        };
 
+       firmware {
+               zynqmp_firmware: zynqmp-firmware {
+                       compatible = "xlnx,zynqmp-firmware";
+                       method = "smc";
+
+                       nvmem_firmware {
+                               compatible = "xlnx,zynqmp-nvmem-fw";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               soc_revision: soc_revision@0 {
+                                       reg = <0x0 0x4>;
+                               };
+                       };
+
+                       zynqmp_pcap: pcap {
+                               compatible = "xlnx,zynqmp-pcap-fpga";
+                       };
+               };
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupt-parent = <&gic>;
                             <1 10 0xf08>;
        };
 
+       fpga_full: fpga-full {
+               compatible = "fpga-region";
+               fpga-mgr = <&zynqmp_pcap>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+       };
+
        amba_apu: amba-apu@0 {
                compatible = "simple-bus";
                #address-cells = <2>;
index c9a867a..6a83ba2 100644 (file)
@@ -7,8 +7,6 @@ CONFIG_PREEMPT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_IKCONFIG=y
@@ -29,6 +27,7 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_PROFILING=y
+CONFIG_ARCH_ACTIONS=y
 CONFIG_ARCH_AGILEX=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
@@ -48,6 +47,7 @@ CONFIG_ARCH_MXC=y
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_RENESAS=y
 CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ARCH_S32=y
 CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_STRATIX10=y
 CONFIG_ARCH_SYNQUACER=y
@@ -71,6 +71,7 @@ CONFIG_COMPAT=y
 CONFIG_RANDOMIZE_BASE=y
 CONFIG_HIBERNATION=y
 CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ENERGY_MODEL=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_CPU_FREQ=y
@@ -90,7 +91,7 @@ CONFIG_ARM_TEGRA186_CPUFREQ=y
 CONFIG_ARM_SCPI_PROTOCOL=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_INTEL_STRATIX10_SERVICE=y
-CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_INTEL_STRATIX10_RSU=m
 CONFIG_EFI_CAPSULE_LOADER=y
 CONFIG_IMX_SCU=y
 CONFIG_IMX_SCU_PD=y
@@ -121,7 +122,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_KSM=y
 CONFIG_MEMORY_FAILURE=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -205,12 +205,12 @@ CONFIG_HISILICON_LPC=y
 CONFIG_SIMPLE_PM_BUS=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_VIRTIO_BLK=y
@@ -265,18 +265,12 @@ CONFIG_HNS3_ENET=y
 CONFIG_E1000E=y
 CONFIG_IGB=y
 CONFIG_IGBVF=y
-CONFIG_MLX4_EN=m
-CONFIG_MLX4_CORE=m
-CONFIG_MLX4_DEBUG=y
-CONFIG_MLX4_CORE_GEN2=y
-CONFIG_MLX5_CORE=m
-CONFIG_MLX5_CORE_EN=y
-CONFIG_MLX5_EN_ARFS=y
-CONFIG_MLX5_EN_RXNFC=y
-CONFIG_MLX5_MPFS=y
 CONFIG_MVNETA=y
 CONFIG_MVPP2=y
 CONFIG_SKY2=y
+CONFIG_MLX4_EN=m
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_CORE_EN=y
 CONFIG_QCOM_EMAC=m
 CONFIG_RAVB=y
 CONFIG_SMC91X=y
@@ -285,11 +279,11 @@ CONFIG_SNI_AVE=y
 CONFIG_SNI_NETSEC=y
 CONFIG_STMMAC_ETH=m
 CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_AT803X_PHY=m
 CONFIG_MARVELL_PHY=m
 CONFIG_MARVELL_10G_PHY=m
 CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
+CONFIG_AT803X_PHY=y
 CONFIG_REALTEK_PHY=m
 CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=m
@@ -314,6 +308,7 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_ADC=m
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_SNVS_PWRKEY=m
+CONFIG_KEYBOARD_IMX_SC_KEY=m
 CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
@@ -352,6 +347,8 @@ CONFIG_SERIAL_XILINX_PS_UART=y
 CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
 CONFIG_SERIAL_FSL_LPUART=y
 CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_FSL_LINFLEXUART=y
+CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
 CONFIG_SERIAL_MVEBU_UART=y
 CONFIG_SERIAL_DEV_BUS=y
 CONFIG_VIRTIO_CONSOLE=y
@@ -392,8 +389,8 @@ CONFIG_SPI_PL022=y
 CONFIG_SPI_ROCKCHIP=y
 CONFIG_SPI_QUP=y
 CONFIG_SPI_S3C64XX=y
-CONFIG_SPI_SPIDEV=m
 CONFIG_SPI_SUN6I=y
+CONFIG_SPI_SPIDEV=m
 CONFIG_SPMI=y
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_PINCTRL_MAX77620=y
@@ -411,6 +408,7 @@ CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_PINCTRL_SDM845=y
 CONFIG_PINCTRL_SM8150=y
+CONFIG_GPIO_ALTERA=m
 CONFIG_GPIO_DWAPB=y
 CONFIG_GPIO_MB86S7X=y
 CONFIG_GPIO_PL061=y
@@ -466,8 +464,6 @@ CONFIG_MFD_ALTERA_SYSMGR=y
 CONFIG_MFD_BD9571MWV=y
 CONFIG_MFD_AXP20X_I2C=y
 CONFIG_MFD_AXP20X_RSB=y
-CONFIG_MFD_CROS_EC=y
-CONFIG_MFD_CROS_EC_CHARDEV=m
 CONFIG_MFD_EXYNOS_LPASS=m
 CONFIG_MFD_HI6421_PMIC=y
 CONFIG_MFD_HI655X_PMIC=y
@@ -662,9 +658,9 @@ CONFIG_RTC_DRV_SNVS=m
 CONFIG_RTC_DRV_IMX_SC=m
 CONFIG_RTC_DRV_XGENE=y
 CONFIG_DMADEVICES=y
-CONFIG_FSL_EDMA=y
 CONFIG_DMA_BCM2835=m
 CONFIG_DMA_SUN6I=m
+CONFIG_FSL_EDMA=y
 CONFIG_IMX_SDMA=y
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
@@ -683,6 +679,7 @@ CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_XEN_GNTDEV=y
 CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_MFD_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_COMMON_CLK_RK808=y
@@ -716,7 +713,6 @@ CONFIG_ARM_MHU=y
 CONFIG_IMX_MBOX=y
 CONFIG_PLATFORM_MHU=y
 CONFIG_BCM2835_MBOX=y
-CONFIG_TI_MESSAGE_MANAGER=y
 CONFIG_QCOM_APCS_IPC=y
 CONFIG_ROCKCHIP_IOMMU=y
 CONFIG_TEGRA_IOMMU_SMMU=y
@@ -732,7 +728,6 @@ CONFIG_RPMSG_QCOM_GLINK_SMEM=m
 CONFIG_RPMSG_QCOM_SMD=y
 CONFIG_RASPBERRYPI_POWER=y
 CONFIG_IMX_SCU_SOC=y
-CONFIG_QCOM_COMMAND_DB=y
 CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_GLINK_SSR=m
 CONFIG_QCOM_RPMH=y
@@ -741,9 +736,11 @@ CONFIG_QCOM_SMD_RPM=y
 CONFIG_QCOM_SMP2P=y
 CONFIG_QCOM_SMSM=y
 CONFIG_ARCH_R8A774A1=y
+CONFIG_ARCH_R8A774B1=y
 CONFIG_ARCH_R8A774C0=y
 CONFIG_ARCH_R8A7795=y
 CONFIG_ARCH_R8A7796=y
+CONFIG_ARCH_R8A77961=y
 CONFIG_ARCH_R8A77965=y
 CONFIG_ARCH_R8A77970=y
 CONFIG_ARCH_R8A77980=y
@@ -756,9 +753,7 @@ CONFIG_ARCH_TEGRA_186_SOC=y
 CONFIG_ARCH_TEGRA_194_SOC=y
 CONFIG_ARCH_K3_AM6_SOC=y
 CONFIG_ARCH_K3_J721E_SOC=y
-CONFIG_SOC_TI=y
 CONFIG_TI_SCI_PM_DOMAINS=y
-CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_EXTCON_USBC_CROS_EC=y
 CONFIG_MEMORY=y
@@ -801,15 +796,16 @@ CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PHY_UNIPHIER_USB2=y
 CONFIG_PHY_UNIPHIER_USB3=y
 CONFIG_PHY_TEGRA_XUSB=y
+CONFIG_ARM_SMMU_V3_PMU=m
 CONFIG_FSL_IMX8_DDR_PMU=m
 CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
-CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_NVMEM_IMX_OCOTP=y
 CONFIG_NVMEM_IMX_OCOTP_SCU=y
 CONFIG_QCOM_QFPROM=y
 CONFIG_ROCKCHIP_EFUSE=y
+CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_UNIPHIER_EFUSE=y
 CONFIG_MESON_EFUSE=m
 CONFIG_FPGA=y
@@ -848,7 +844,8 @@ CONFIG_NLS_ISO8859_1=y
 CONFIG_SECURITY=y
 CONFIG_CRYPTO_ECHAINIV=y
 CONFIG_CRYPTO_ANSI_CPRNG=y
-CONFIG_DMA_CMA=y
+CONFIG_CRYPTO_DEV_SUN8I_CE=m
+CONFIG_CRYPTO_DEV_HISI_ZIP=m
 CONFIG_CMA_SIZE_MBYTES=32
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
index befe37d..53d846f 100644 (file)
@@ -91,6 +91,7 @@ alternative_cb_end
 
 void kvm_update_va_mask(struct alt_instr *alt,
                        __le32 *origptr, __le32 *updptr, int nr_inst);
+void kvm_compute_layout(void);
 
 static inline unsigned long __kern_hyp_va(unsigned long v)
 {
index 788ae97..25a73aa 100644 (file)
@@ -15,6 +15,7 @@ extern char __hyp_text_start[], __hyp_text_end[];
 extern char __idmap_text_start[], __idmap_text_end[];
 extern char __initdata_begin[], __initdata_end[];
 extern char __inittext_begin[], __inittext_end[];
+extern char __exittext_begin[], __exittext_end[];
 extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
index 127712b..32fc806 100644 (file)
@@ -62,8 +62,13 @@ static inline unsigned long __range_ok(const void __user *addr, unsigned long si
 {
        unsigned long ret, limit = current_thread_info()->addr_limit;
 
+       /*
+        * Asynchronous I/O running in a kernel thread does not have the
+        * TIF_TAGGED_ADDR flag of the process owning the mm, so always untag
+        * the user address before checking.
+        */
        if (IS_ENABLED(CONFIG_ARM64_TAGGED_ADDR_ABI) &&
-           test_thread_flag(TIF_TAGGED_ADDR))
+           (current->flags & PF_KTHREAD || test_thread_flag(TIF_TAGGED_ADDR)))
                addr = untagged_addr(addr);
 
        __chk_user_ptr(addr);
index 4fe1514..7d02f99 100644 (file)
@@ -133,7 +133,6 @@ ENTRY(ftrace_graph_caller)
        bl      prepare_ftrace_return
        b       ftrace_common_return
 ENDPROC(ftrace_graph_caller)
-#else
 #endif
 
 #else /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
@@ -287,6 +286,7 @@ GLOBAL(ftrace_graph_call)           // ftrace_graph_caller();
 
        mcount_exit
 ENDPROC(ftrace_caller)
+#endif /* CONFIG_DYNAMIC_FTRACE */
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 /*
@@ -307,7 +307,6 @@ ENTRY(ftrace_graph_caller)
        mcount_exit
 ENDPROC(ftrace_graph_caller)
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-#endif /* CONFIG_DYNAMIC_FTRACE */
 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
 
 ENTRY(ftrace_stub)
index 583f71a..7c6a0a4 100644 (file)
@@ -76,7 +76,8 @@ alternative_else_nop_endif
 #ifdef CONFIG_VMAP_STACK
        /*
         * Test whether the SP has overflowed, without corrupting a GPR.
-        * Task and IRQ stacks are aligned to (1 << THREAD_SHIFT).
+        * Task and IRQ stacks are aligned so that SP & (1 << THREAD_SHIFT)
+        * should always be zero.
         */
        add     sp, sp, x0                      // sp' = sp + x0
        sub     x0, sp, x0                      // x0' = sp' - x0 = (sp + x0) - x0 = sp
index 513b29c..4a9e773 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/fixmap.h>
 #include <asm/insn.h>
 #include <asm/kprobes.h>
+#include <asm/sections.h>
 
 #define AARCH64_INSN_SF_BIT    BIT(31)
 #define AARCH64_INSN_N_BIT     BIT(22)
@@ -78,16 +79,29 @@ bool aarch64_insn_is_branch_imm(u32 insn)
 
 static DEFINE_RAW_SPINLOCK(patch_lock);
 
+static bool is_exit_text(unsigned long addr)
+{
+       /* discarded with init text/data */
+       return system_state < SYSTEM_RUNNING &&
+               addr >= (unsigned long)__exittext_begin &&
+               addr < (unsigned long)__exittext_end;
+}
+
+static bool is_image_text(unsigned long addr)
+{
+       return core_kernel_text(addr) || is_exit_text(addr);
+}
+
 static void __kprobes *patch_map(void *addr, int fixmap)
 {
        unsigned long uintaddr = (uintptr_t) addr;
-       bool module = !core_kernel_text(uintaddr);
+       bool image = is_image_text(uintaddr);
        struct page *page;
 
-       if (module && IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
-               page = vmalloc_to_page(addr);
-       else if (!module)
+       if (image)
                page = phys_to_page(__pa_symbol(addr));
+       else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
+               page = vmalloc_to_page(addr);
        else
                return addr;
 
index ab149bc..d4ed9a1 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/of.h>
 #include <linux/irq_work.h>
 #include <linux/kexec.h>
+#include <linux/kvm_host.h>
 
 #include <asm/alternative.h>
 #include <asm/atomic.h>
@@ -39,6 +40,7 @@
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
 #include <asm/daifflags.h>
+#include <asm/kvm_mmu.h>
 #include <asm/mmu_context.h>
 #include <asm/numa.h>
 #include <asm/pgtable.h>
@@ -407,6 +409,8 @@ static void __init hyp_mode_check(void)
                           "CPU: CPUs started in inconsistent modes");
        else
                pr_info("CPU: All CPU(s) started at EL1\n");
+       if (IS_ENABLED(CONFIG_KVM_ARM_HOST))
+               kvm_compute_layout();
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
index 841a8b4..497f967 100644 (file)
@@ -158,9 +158,12 @@ SECTIONS
        __inittext_begin = .;
 
        INIT_TEXT_SECTION(8)
+
+       __exittext_begin = .;
        .exit.text : {
                ARM_EXIT_KEEP(EXIT_TEXT)
        }
+       __exittext_end = .;
 
        . = ALIGN(4);
        .altinstructions : {
index 2cf7d4b..dab1fea 100644 (file)
@@ -22,7 +22,7 @@ static u8 tag_lsb;
 static u64 tag_val;
 static u64 va_mask;
 
-static void compute_layout(void)
+__init void kvm_compute_layout(void)
 {
        phys_addr_t idmap_addr = __pa_symbol(__hyp_idmap_text_start);
        u64 hyp_va_msb;
@@ -110,9 +110,6 @@ void __init kvm_update_va_mask(struct alt_instr *alt,
 
        BUG_ON(nr_inst != 5);
 
-       if (!has_vhe() && !va_mask)
-               compute_layout();
-
        for (i = 0; i < nr_inst; i++) {
                u32 rd, rn, insn, oinsn;
 
@@ -156,9 +153,6 @@ void kvm_patch_vector_branch(struct alt_instr *alt,
                return;
        }
 
-       if (!va_mask)
-               compute_layout();
-
        /*
         * Compute HYP VA by using the same computation as kern_hyp_va()
         */
index 93f9f77..0a920b5 100644 (file)
@@ -142,6 +142,7 @@ static const struct prot_bits pte_bits[] = {
                .mask   = PTE_UXN,
                .val    = PTE_UXN,
                .set    = "UXN",
+               .clear  = "   ",
        }, {
                .mask   = PTE_ATTRINDX_MASK,
                .val    = PTE_ATTRINDX(MT_DEVICE_nGnRnE),
index be9481c..b65dffd 100644 (file)
@@ -214,15 +214,14 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
        struct memblock_region *reg;
        unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
-       unsigned long max_dma32 = min;
-       unsigned long __maybe_unused max_dma = min;
+       unsigned long __maybe_unused max_dma, max_dma32;
 
        memset(zone_size, 0, sizeof(zone_size));
 
+       max_dma = max_dma32 = min;
 #ifdef CONFIG_ZONE_DMA
-       max_dma = PFN_DOWN(arm64_dma_phys_limit);
+       max_dma = max_dma32 = PFN_DOWN(arm64_dma_phys_limit);
        zone_size[ZONE_DMA] = max_dma - min;
-       max_dma32 = max_dma;
 #endif
 #ifdef CONFIG_ZONE_DMA32
        max_dma32 = PFN_DOWN(arm64_dma32_phys_limit);
@@ -236,25 +235,23 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
                unsigned long start = memblock_region_memory_base_pfn(reg);
                unsigned long end = memblock_region_memory_end_pfn(reg);
 
-               if (start >= max)
-                       continue;
 #ifdef CONFIG_ZONE_DMA
-               if (start < max_dma) {
-                       unsigned long dma_end = min_not_zero(end, max_dma);
+               if (start >= min && start < max_dma) {
+                       unsigned long dma_end = min(end, max_dma);
                        zhole_size[ZONE_DMA] -= dma_end - start;
+                       start = dma_end;
                }
 #endif
 #ifdef CONFIG_ZONE_DMA32
-               if (start < max_dma32) {
+               if (start >= max_dma && start < max_dma32) {
                        unsigned long dma32_end = min(end, max_dma32);
-                       unsigned long dma32_start = max(start, max_dma);
-                       zhole_size[ZONE_DMA32] -= dma32_end - dma32_start;
+                       zhole_size[ZONE_DMA32] -= dma32_end - start;
+                       start = dma32_end;
                }
 #endif
-               if (end > max_dma32) {
+               if (start >= max_dma32 && start < max) {
                        unsigned long normal_end = min(end, max);
-                       unsigned long normal_start = max(start, max_dma32);
-                       zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
+                       zhole_size[ZONE_NORMAL] -= normal_end - start;
                }
        }
 
index 0b6919c..197c473 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef _ASM_C6X_PGTABLE_H
 #define _ASM_C6X_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
index 2b451c4..0261507 100644 (file)
@@ -14,8 +14,8 @@
  * in coherent mode, which lets us map the AGP memory as normal (write-back) memory
  * (unlike x86, where it gets mapped "write-coalescing").
  */
-#define map_page_into_agp(page)                /* nothing */
-#define unmap_page_from_agp(page)      /* nothing */
+#define map_page_into_agp(page)                do { } while (0)
+#define unmap_page_from_agp(page)      do { } while (0)
 #define flush_agp_cache()              mb()
 
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
index d97f843..1dc30f1 100644 (file)
@@ -36,11 +36,7 @@ static inline void arch_maybe_save_ip(unsigned long flags)
 static inline unsigned long arch_local_save_flags(void)
 {
        ia64_stop();
-#ifdef CONFIG_PARAVIRT
-       return ia64_get_psr_i();
-#else
        return ia64_getreg(_IA64_REG_PSR);
-#endif
 }
 
 static inline unsigned long arch_local_irq_save(void)
index c60696f..ecfa3ea 100644 (file)
@@ -31,7 +31,7 @@ extern void ia64_bad_param_for_setreg (void);
 extern void ia64_bad_param_for_getreg (void);
 
 
-#define ia64_native_setreg(regnum, val)                                                \
+#define ia64_setreg(regnum, val)                                               \
 ({                                                                             \
        switch (regnum) {                                                       \
            case _IA64_REG_PSR_L:                                               \
@@ -60,7 +60,7 @@ extern void ia64_bad_param_for_getreg (void);
        }                                                                       \
 })
 
-#define ia64_native_getreg(regnum)                                             \
+#define ia64_getreg(regnum)                                                    \
 ({                                                                             \
        __u64 ia64_intri_res;                                                   \
                                                                                \
@@ -384,7 +384,7 @@ extern void ia64_bad_param_for_getreg (void);
 
 #define ia64_invala() asm volatile ("invala" ::: "memory")
 
-#define ia64_native_thash(addr)                                                        \
+#define ia64_thash(addr)                                                       \
 ({                                                                             \
        unsigned long ia64_intri_res;                                           \
        asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr));       \
@@ -437,10 +437,10 @@ extern void ia64_bad_param_for_getreg (void);
 #define ia64_set_pmd(index, val)                                               \
        asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
 
-#define ia64_native_set_rr(index, val)                                                 \
+#define ia64_set_rr(index, val)                                                        \
        asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
 
-#define ia64_native_get_cpuid(index)                                                   \
+#define ia64_get_cpuid(index)                                                          \
 ({                                                                                     \
        unsigned long ia64_intri_res;                                                   \
        asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index));        \
@@ -476,33 +476,33 @@ extern void ia64_bad_param_for_getreg (void);
 })
 
 
-#define ia64_native_get_pmd(index)                                             \
+#define ia64_get_pmd(index)                                                    \
 ({                                                                             \
        unsigned long ia64_intri_res;                                           \
        asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index));    \
        ia64_intri_res;                                                         \
 })
 
-#define ia64_native_get_rr(index)                                              \
+#define ia64_get_rr(index)                                                     \
 ({                                                                             \
        unsigned long ia64_intri_res;                                           \
        asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index));    \
        ia64_intri_res;                                                         \
 })
 
-#define ia64_native_fc(addr)   asm volatile ("fc %0" :: "r"(addr) : "memory")
+#define ia64_fc(addr)  asm volatile ("fc %0" :: "r"(addr) : "memory")
 
 
 #define ia64_sync_i()  asm volatile (";; sync.i" ::: "memory")
 
-#define ia64_native_ssm(mask)  asm volatile ("ssm %0":: "i"((mask)) : "memory")
-#define ia64_native_rsm(mask)  asm volatile ("rsm %0":: "i"((mask)) : "memory")
+#define ia64_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
+#define ia64_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
 #define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
 #define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
 
 #define ia64_ptce(addr)        asm volatile ("ptc.e %0" :: "r"(addr))
 
-#define ia64_native_ptcga(addr, size)                                          \
+#define ia64_ptcga(addr, size)                                                 \
 do {                                                                           \
        asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory");       \
        ia64_dv_serialize_data();                                               \
@@ -607,7 +607,7 @@ do {                                                                                \
         }                                                              \
 })
 
-#define ia64_native_intrin_local_irq_restore(x)                        \
+#define ia64_intrin_local_irq_restore(x)                       \
 do {                                                           \
        asm volatile (";;   cmp.ne p6,p7=%0,r0;;"               \
                      "(p6) ssm psr.i;"                         \
index ab64969..dc1884d 100644 (file)
@@ -17,8 +17,8 @@
                         * intrinsic
                         */
 
-#define ia64_native_getreg     __getReg
-#define ia64_native_setreg     __setReg
+#define ia64_getreg            __getReg
+#define ia64_setreg            __setReg
 
 #define ia64_hint              __hint
 #define ia64_hint_pause                __hint_pause
 #define ia64_invala_fr         __invala_fr
 #define ia64_nop               __nop
 #define ia64_sum               __sum
-#define ia64_native_ssm                __ssm
+#define ia64_ssm               __ssm
 #define ia64_rum               __rum
-#define ia64_native_rsm                __rsm
-#define ia64_native_fc                 __fc
+#define ia64_rsm               __rsm
+#define ia64_fc                        __fc
 
 #define ia64_ldfs              __ldfs
 #define ia64_ldfd              __ldfd
                __setIndReg(_IA64_REG_INDR_PMC, index, val)
 #define ia64_set_pmd(index, val)       \
                __setIndReg(_IA64_REG_INDR_PMD, index, val)
-#define ia64_native_set_rr(index, val) \
+#define ia64_set_rr(index, val)                \
                __setIndReg(_IA64_REG_INDR_RR, index, val)
 
-#define ia64_native_get_cpuid(index)   \
+#define ia64_get_cpuid(index)  \
                __getIndReg(_IA64_REG_INDR_CPUID, index)
 #define __ia64_get_dbr(index)          __getIndReg(_IA64_REG_INDR_DBR, index)
 #define ia64_get_ibr(index)            __getIndReg(_IA64_REG_INDR_IBR, index)
 #define ia64_get_pkr(index)            __getIndReg(_IA64_REG_INDR_PKR, index)
 #define ia64_get_pmc(index)            __getIndReg(_IA64_REG_INDR_PMC, index)
-#define ia64_native_get_pmd(index)     __getIndReg(_IA64_REG_INDR_PMD, index)
-#define ia64_native_get_rr(index)      __getIndReg(_IA64_REG_INDR_RR, index)
+#define ia64_get_pmd(index)            __getIndReg(_IA64_REG_INDR_PMD, index)
+#define ia64_get_rr(index)             __getIndReg(_IA64_REG_INDR_RR, index)
 
 #define ia64_srlz_d            __dsrlz
 #define ia64_srlz_i            __isrlz
 #define ia64_ld8_acq           __ld8_acq
 
 #define ia64_sync_i            __synci
-#define ia64_native_thash      __thash
-#define ia64_native_ttag       __ttag
+#define ia64_thash             __thash
+#define ia64_ttag              __ttag
 #define ia64_itcd              __itcd
 #define ia64_itci              __itci
 #define ia64_itrd              __itrd
 #define ia64_itri              __itri
 #define ia64_ptce              __ptce
 #define ia64_ptcl              __ptcl
-#define ia64_native_ptcg       __ptcg
-#define ia64_native_ptcga      __ptcga
+#define ia64_ptcg              __ptcg
+#define ia64_ptcga             __ptcga
 #define ia64_ptri              __ptri
 #define ia64_ptrd              __ptrd
 #define ia64_dep_mi            _m64_dep_mi
 #define ia64_lfetch_fault      __lfetch_fault
 #define ia64_lfetch_fault_excl __lfetch_fault_excl
 
-#define ia64_native_intrin_local_irq_restore(x)                \
+#define ia64_intrin_local_irq_restore(x)               \
 do {                                                   \
        if ((x) != 0) {                                 \
-               ia64_native_ssm(IA64_PSR_I);            \
+               ia64_ssm(IA64_PSR_I);                   \
                ia64_srlz_d();                          \
        } else {                                        \
-               ia64_native_rsm(IA64_PSR_I);            \
+               ia64_rsm(IA64_PSR_I);                   \
        }                                               \
 } while (0)
 
index aecc217..a0e0a06 100644 (file)
 #endif
 #include <asm/cmpxchg.h>
 
-#define ia64_native_get_psr_i()        (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
-
-#define ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4)       \
+#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4)              \
 do {                                                                   \
-       ia64_native_set_rr(0x0000000000000000UL, (val0));               \
-       ia64_native_set_rr(0x2000000000000000UL, (val1));               \
-       ia64_native_set_rr(0x4000000000000000UL, (val2));               \
-       ia64_native_set_rr(0x6000000000000000UL, (val3));               \
-       ia64_native_set_rr(0x8000000000000000UL, (val4));               \
+       ia64_set_rr(0x0000000000000000UL, (val0));                      \
+       ia64_set_rr(0x2000000000000000UL, (val1));                      \
+       ia64_set_rr(0x4000000000000000UL, (val2));                      \
+       ia64_set_rr(0x6000000000000000UL, (val3));                      \
+       ia64_set_rr(0x8000000000000000UL, (val4));                      \
 } while (0)
 
 /*
@@ -85,41 +83,4 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
 
 #endif
 
-
-#ifndef __ASSEMBLY__
-
-#define IA64_INTRINSIC_API(name)       ia64_native_ ## name
-#define IA64_INTRINSIC_MACRO(name)     ia64_native_ ## name
-
-
-/************************************************/
-/* Instructions paravirtualized for correctness */
-/************************************************/
-/* fc, thash, get_cpuid, get_pmd, get_eflags, set_eflags */
-/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
- * is not currently used (though it may be in a long-format VHPT system!)
- */
-#define ia64_fc                                IA64_INTRINSIC_API(fc)
-#define ia64_thash                     IA64_INTRINSIC_API(thash)
-#define ia64_get_cpuid                 IA64_INTRINSIC_API(get_cpuid)
-#define ia64_get_pmd                   IA64_INTRINSIC_API(get_pmd)
-
-
-/************************************************/
-/* Instructions paravirtualized for performance */
-/************************************************/
-#define ia64_ssm                       IA64_INTRINSIC_MACRO(ssm)
-#define ia64_rsm                       IA64_INTRINSIC_MACRO(rsm)
-#define ia64_getreg                    IA64_INTRINSIC_MACRO(getreg)
-#define ia64_setreg                    IA64_INTRINSIC_API(setreg)
-#define ia64_set_rr                    IA64_INTRINSIC_API(set_rr)
-#define ia64_get_rr                    IA64_INTRINSIC_API(get_rr)
-#define ia64_ptcga                     IA64_INTRINSIC_API(ptcga)
-#define ia64_get_psr_i                 IA64_INTRINSIC_API(get_psr_i)
-#define ia64_intrin_local_irq_restore  \
-       IA64_INTRINSIC_API(intrin_local_irq_restore)
-#define ia64_set_rr0_to_rr4            IA64_INTRINSIC_API(set_rr0_to_rr4)
-
-#endif /* !__ASSEMBLY__ */
-
 #endif /* _UAPI_ASM_IA64_INTRINSICS_H */
index 52d312d..d43a027 100644 (file)
@@ -108,7 +108,7 @@ ret_from_exception:
        btst    #5,%sp@(PT_OFF_SR)      /* check if returning to kernel */
        jeq     Luser_return            /* if so, skip resched, signals */
 
-#ifdef CONFIG_PREEMPT
+#ifdef CONFIG_PREEMPTION
        movel   %sp,%d1                 /* get thread_info pointer */
        andl    #-THREAD_SIZE,%d1       /* at base of kernel stack */
        movel   %d1,%a0
index b34d44d..82ec54c 100644 (file)
@@ -28,9 +28,6 @@ extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
        return (pmd_t *) pgd;
 }
 
-#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
-#define pmd_alloc_one(mm, address)      ({ BUG(); ((pmd_t *)2); })
-
 #define pmd_populate(mm, pmd, page) (pmd_val(*pmd) = \
        (unsigned long)(page_address(page)))
 
@@ -45,8 +42,6 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
        __free_page(page);
 }
 
-#define __pmd_free_tlb(tlb, pmd, address) do { } while (0)
-
 static inline struct page *pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page = alloc_pages(GFP_DMA, 0);
@@ -100,6 +95,4 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
        return new_pgd;
 }
 
-#define pgd_populate(mm, pmd, pte) BUG()
-
 #endif /* M68K_MCF_PGALLOC_H */
index 5d5502c..b9f45ae 100644 (file)
@@ -198,17 +198,9 @@ static inline int pmd_bad2(pmd_t *pmd) { return 0; }
 #define pmd_present(pmd) (!pmd_none2(&(pmd)))
 static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; }
 
-static inline int pgd_none(pgd_t pgd) { return 0; }
-static inline int pgd_bad(pgd_t pgd) { return 0; }
-static inline int pgd_present(pgd_t pgd) { return 1; }
-static inline void pgd_clear(pgd_t *pgdp) {}
-
 #define pte_ERROR(e) \
        printk(KERN_ERR "%s:%d: bad pte %08lx.\n",      \
        __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
-       printk(KERN_ERR "%s:%d: bad pmd %08lx.\n",      \
-       __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
        printk(KERN_ERR "%s:%d: bad pgd %08lx.\n",      \
        __FILE__, __LINE__, pgd_val(e))
@@ -340,14 +332,6 @@ extern pgd_t kernel_pg_dir[PTRS_PER_PGD];
 #define pgd_offset_k(address)  pgd_offset(&init_mm, address)
 
 /*
- * Find an entry in the second-level pagetable.
- */
-static inline pmd_t *pmd_offset(pgd_t *pgd, unsigned long address)
-{
-       return (pmd_t *) pgd;
-}
-
-/*
  * Find an entry in the third-level pagetable.
  */
 #define __pte_offset(address)  ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
@@ -360,12 +344,16 @@ static inline pmd_t *pmd_offset(pgd_t *pgd, unsigned long address)
 static inline void nocache_page(void *vaddr)
 {
        pgd_t *dir;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
        unsigned long addr = (unsigned long) vaddr;
 
        dir = pgd_offset_k(addr);
-       pmdp = pmd_offset(dir, addr);
+       p4dp = p4d_offset(dir, addr);
+       pudp = pud_offset(p4dp, addr);
+       pmdp = pmd_offset(pudp, addr);
        ptep = pte_offset_kernel(pmdp, addr);
        *ptep = pte_mknocache(*ptep);
 }
@@ -376,12 +364,16 @@ static inline void nocache_page(void *vaddr)
 static inline void cache_page(void *vaddr)
 {
        pgd_t *dir;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
        unsigned long addr = (unsigned long) vaddr;
 
        dir = pgd_offset_k(addr);
-       pmdp = pmd_offset(dir, addr);
+       p4dp = p4d_offset(dir, addr);
+       pudp = pud_offset(p4dp, addr);
+       pmdp = pmd_offset(pudp, addr);
        ptep = pte_offset_kernel(pmdp, addr);
        *ptep = pte_mkcache(*ptep);
 }
index f5b1852..cac9f28 100644 (file)
@@ -100,6 +100,8 @@ static inline void load_ksp_mmu(struct task_struct *task)
        struct mm_struct *mm;
        int asid;
        pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        unsigned long mmuar;
@@ -127,7 +129,15 @@ static inline void load_ksp_mmu(struct task_struct *task)
        if (pgd_none(*pgd))
                goto bug;
 
-       pmd = pmd_offset(pgd, mmuar);
+       p4d = p4d_offset(pgd, mmuar);
+       if (p4d_none(*p4d))
+               goto bug;
+
+       pud = pud_offset(p4d, mmuar);
+       if (pud_none(*pud))
+               goto bug;
+
+       pmd = pmd_offset(pud, mmuar);
        if (pmd_none(*pmd))
                goto bug;
 
index acab315..ff9cc40 100644 (file)
@@ -106,9 +106,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page
 }
 #define pmd_pgtable(pmd) pmd_page(pmd)
 
-static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
-       pgd_set(pgd, pmd);
+       pud_set(pud, pmd);
 }
 
 #endif /* _MOTOROLA_PGALLOC_H */
index 7f66a7b..62bedc6 100644 (file)
@@ -117,14 +117,14 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
        }
 }
 
-static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
+static inline void pud_set(pud_t *pudp, pmd_t *pmdp)
 {
-       pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp);
+       pud_val(*pudp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp);
 }
 
 #define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
 #define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
-#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK))
+#define pud_page_vaddr(pud) ((unsigned long)__va(pud_val(pud) & _TABLE_MASK))
 
 
 #define pte_none(pte)          (!pte_val(pte))
@@ -147,11 +147,11 @@ static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
 #define pmd_page(pmd)          virt_to_page(__va(pmd_val(pmd)))
 
 
-#define pgd_none(pgd)          (!pgd_val(pgd))
-#define pgd_bad(pgd)           ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE)
-#define pgd_present(pgd)       (pgd_val(pgd) & _PAGE_TABLE)
-#define pgd_clear(pgdp)                ({ pgd_val(*pgdp) = 0; })
-#define pgd_page(pgd)          (mem_map + ((unsigned long)(__va(pgd_val(pgd)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pud_none(pud)          (!pud_val(pud))
+#define pud_bad(pud)           ((pud_val(pud) & _DESCTYPE_MASK) != _PAGE_TABLE)
+#define pud_present(pud)       (pud_val(pud) & _PAGE_TABLE)
+#define pud_clear(pudp)                ({ pud_val(*pudp) = 0; })
+#define pud_page(pud)          (mem_map + ((unsigned long)(__va(pud_val(pud)) - PAGE_OFFSET) >> PAGE_SHIFT))
 
 #define pte_ERROR(e) \
        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
@@ -209,9 +209,9 @@ static inline pgd_t *pgd_offset_k(unsigned long address)
 
 
 /* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
+static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address)
 {
-       return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
+       return (pmd_t *)pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
 }
 
 /* Find an entry in the third-level page table.. */
@@ -239,11 +239,15 @@ static inline void nocache_page(void *vaddr)
 
        if (CPU_IS_040_OR_060) {
                pgd_t *dir;
+               p4d_t *p4dp;
+               pud_t *pudp;
                pmd_t *pmdp;
                pte_t *ptep;
 
                dir = pgd_offset_k(addr);
-               pmdp = pmd_offset(dir, addr);
+               p4dp = p4d_offset(dir, addr);
+               pudp = pud_offset(p4dp, addr);
+               pmdp = pmd_offset(pudp, addr);
                ptep = pte_offset_kernel(pmdp, addr);
                *ptep = pte_mknocache(*ptep);
        }
@@ -255,11 +259,15 @@ static inline void cache_page(void *vaddr)
 
        if (CPU_IS_040_OR_060) {
                pgd_t *dir;
+               p4d_t *p4dp;
+               pud_t *pudp;
                pmd_t *pmdp;
                pte_t *ptep;
 
                dir = pgd_offset_k(addr);
-               pmdp = pmd_offset(dir, addr);
+               p4dp = p4d_offset(dir, addr);
+               pudp = pud_offset(p4dp, addr);
+               pmdp = pmd_offset(pudp, addr);
                ptep = pte_offset_kernel(pmdp, addr);
                *ptep = pte_mkcache(*ptep);
        }
index 700d819..05e1e1e 100644 (file)
 /*
  * These are used to make use of C type-checking..
  */
-typedef struct { unsigned long pte; } pte_t;
+#if !defined(CONFIG_MMU) || CONFIG_PGTABLE_LEVELS == 3
 typedef struct { unsigned long pmd[16]; } pmd_t;
+#define pmd_val(x)     ((&x)->pmd[0])
+#define __pmd(x)       ((pmd_t) { { (x) }, })
+#endif
+
+typedef struct { unsigned long pte; } pte_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 typedef struct page *pgtable_t;
 
 #define pte_val(x)     ((x).pte)
-#define pmd_val(x)     ((&x)->pmd[0])
 #define pgd_val(x)     ((x).pgd)
 #define pgprot_val(x)  ((x).pgprot)
 
 #define __pte(x)       ((pte_t) { (x) } )
-#define __pmd(x)       ((pmd_t) { { (x) }, })
 #define __pgd(x)       ((pgd_t) { (x) } )
 #define __pgprot(x)    ((pgprot_t) { (x) } )
 
index 646c174..2bf5c35 100644 (file)
@@ -2,7 +2,12 @@
 #ifndef _M68K_PGTABLE_H
 #define _M68K_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+
+#if defined(CONFIG_SUN3) || defined(CONFIG_COLDFIRE)
+#include <asm-generic/pgtable-nopmd.h>
+#else
+#include <asm-generic/pgtable-nopud.h>
+#endif
 
 #include <asm/setup.h>
 
@@ -30,9 +35,7 @@
 
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
-#ifdef CONFIG_SUN3
-#define PMD_SHIFT       17
-#else
+#if CONFIG_PGTABLE_LEVELS == 3
 #define PMD_SHIFT      22
 #endif
 #define PMD_SIZE       (1UL << PMD_SHIFT)
index c18165b..ccc4568 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _M68KNOMMU_PGTABLE_H
 #define _M68KNOMMU_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 /*
  * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
index 8561211..11b95da 100644 (file)
@@ -17,8 +17,6 @@
 
 extern const char bad_pmd_string[];
 
-#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
-
 #define __pte_free_tlb(tlb,pte,addr)                   \
 do {                                                   \
        pgtable_pte_page_dtor(pte);                     \
@@ -41,7 +39,6 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page
  * inside the pgd, so has no extra memory associated with it.
  */
 #define pmd_free(mm, x)                        do { } while (0)
-#define __pmd_free_tlb(tlb, x, addr)   do { } while (0)
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
@@ -58,6 +55,4 @@ static inline pgd_t * pgd_alloc(struct mm_struct *mm)
      return new_pgd;
 }
 
-#define pgd_populate(mm, pmd, pte) BUG()
-
 #endif /* SUN3_PGALLOC_H */
index c987d50..bc41552 100644 (file)
@@ -110,11 +110,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 #define pmd_set(pmdp,ptep) do {} while (0)
 
-static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
-{
-       pgd_val(*pgdp) = virt_to_phys(pmdp);
-}
-
 #define __pte_page(pte) \
 ((unsigned long) __va ((pte_val (pte) & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT))
 #define __pmd_page(pmd) \
@@ -145,16 +140,9 @@ static inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_V
 #define pmd_present(pmd) (!pmd_none2(&(pmd)))
 static inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; }
 
-static inline int pgd_none (pgd_t pgd) { return 0; }
-static inline int pgd_bad (pgd_t pgd) { return 0; }
-static inline int pgd_present (pgd_t pgd) { return 1; }
-static inline void pgd_clear (pgd_t *pgdp) {}
-
 
 #define pte_ERROR(e) \
        pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
-       pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
        pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
@@ -194,12 +182,6 @@ extern pgd_t kernel_pg_dir[PTRS_PER_PGD];
 /* Find an entry in a kernel pagetable directory. */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-/* Find an entry in the second-level pagetable. */
-static inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address)
-{
-       return (pmd_t *) pgd;
-}
-
 /* Find an entry in the third-level pagetable. */
 #define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
 #define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address))
index 6363ec8..18a4de7 100644 (file)
@@ -465,6 +465,8 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
        for (;;) {
                struct mm_struct *mm = current->mm;
                pgd_t *pgd;
+               p4d_t *p4d;
+               pud_t *pud;
                pmd_t *pmd;
                pte_t *pte;
                spinlock_t *ptl;
@@ -474,7 +476,13 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
                pgd = pgd_offset(mm, (unsigned long)mem);
                if (!pgd_present(*pgd))
                        goto bad_access;
-               pmd = pmd_offset(pgd, (unsigned long)mem);
+               p4d = p4d_offset(pgd, (unsigned long)mem);
+               if (!p4d_present(*p4d))
+                       goto bad_access;
+               pud = pud_offset(p4d, (unsigned long)mem);
+               if (!pud_present(*pud))
+                       goto bad_access;
+               pmd = pmd_offset(pud, (unsigned long)mem);
                if (!pmd_present(*pmd))
                        goto bad_access;
                pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
index 778cacb..27c453f 100644 (file)
@@ -130,8 +130,10 @@ static inline void init_pointer_tables(void)
        /* insert pointer tables allocated so far into the tablelist */
        init_pointer_table((unsigned long)kernel_pg_dir);
        for (i = 0; i < PTRS_PER_PGD; i++) {
-               if (pgd_present(kernel_pg_dir[i]))
-                       init_pointer_table(__pgd_page(kernel_pg_dir[i]));
+               pud_t *pud = (pud_t *)(&kernel_pg_dir[i]);
+
+               if (pud_present(*pud))
+                       init_pointer_table(pgd_page_vaddr(kernel_pg_dir[i]));
        }
 
        /* insert also pointer table that we used to unmap the zero page */
index 23f9466..120030a 100644 (file)
@@ -63,18 +63,23 @@ static void __free_io_area(void *addr, unsigned long size)
 {
        unsigned long virtaddr = (unsigned long)addr;
        pgd_t *pgd_dir;
+       p4d_t *p4d_dir;
+       pud_t *pud_dir;
        pmd_t *pmd_dir;
        pte_t *pte_dir;
 
        while ((long)size > 0) {
                pgd_dir = pgd_offset_k(virtaddr);
-               if (pgd_bad(*pgd_dir)) {
-                       printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
-                       pgd_clear(pgd_dir);
+               p4d_dir = p4d_offset(pgd_dir, virtaddr);
+               pud_dir = pud_offset(p4d_dir, virtaddr);
+               if (pud_bad(*pud_dir)) {
+                       printk("iounmap: bad pud(%08lx)\n", pud_val(*pud_dir));
+                       pud_clear(pud_dir);
                        return;
                }
-               pmd_dir = pmd_offset(pgd_dir, virtaddr);
+               pmd_dir = pmd_offset(pud_dir, virtaddr);
 
+#if CONFIG_PGTABLE_LEVELS == 3
                if (CPU_IS_020_OR_030) {
                        int pmd_off = (virtaddr/PTRTREESIZE) & 15;
                        int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
@@ -87,6 +92,7 @@ static void __free_io_area(void *addr, unsigned long size)
                        } else if (pmd_type == 0)
                                continue;
                }
+#endif
 
                if (pmd_bad(*pmd_dir)) {
                        printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
@@ -159,6 +165,8 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
        unsigned long virtaddr, retaddr;
        long offset;
        pgd_t *pgd_dir;
+       p4d_t *p4d_dir;
+       pud_t *pud_dir;
        pmd_t *pmd_dir;
        pte_t *pte_dir;
 
@@ -245,18 +253,23 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
                        printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
 #endif
                pgd_dir = pgd_offset_k(virtaddr);
-               pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);
+               p4d_dir = p4d_offset(pgd_dir, virtaddr);
+               pud_dir = pud_offset(p4d_dir, virtaddr);
+               pmd_dir = pmd_alloc(&init_mm, pud_dir, virtaddr);
                if (!pmd_dir) {
                        printk("ioremap: no mem for pmd_dir\n");
                        return NULL;
                }
 
+#if CONFIG_PGTABLE_LEVELS == 3
                if (CPU_IS_020_OR_030) {
                        pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
                        physaddr += PTRTREESIZE;
                        virtaddr += PTRTREESIZE;
                        size -= PTRTREESIZE;
-               } else {
+               } else
+#endif
+               {
                        pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
                        if (!pte_dir) {
                                printk("ioremap: no mem for pte_dir\n");
@@ -307,6 +320,8 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
 {
        unsigned long virtaddr = (unsigned long)addr;
        pgd_t *pgd_dir;
+       p4d_t *p4d_dir;
+       pud_t *pud_dir;
        pmd_t *pmd_dir;
        pte_t *pte_dir;
 
@@ -341,13 +356,16 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
 
        while ((long)size > 0) {
                pgd_dir = pgd_offset_k(virtaddr);
-               if (pgd_bad(*pgd_dir)) {
-                       printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
-                       pgd_clear(pgd_dir);
+               p4d_dir = p4d_offset(pgd_dir, virtaddr);
+               pud_dir = pud_offset(p4d_dir, virtaddr);
+               if (pud_bad(*pud_dir)) {
+                       printk("iocachemode: bad pud(%08lx)\n", pud_val(*pud_dir));
+                       pud_clear(pud_dir);
                        return;
                }
-               pmd_dir = pmd_offset(pgd_dir, virtaddr);
+               pmd_dir = pmd_offset(pud_dir, virtaddr);
 
+#if CONFIG_PGTABLE_LEVELS == 3
                if (CPU_IS_020_OR_030) {
                        int pmd_off = (virtaddr/PTRTREESIZE) & 15;
 
@@ -359,6 +377,7 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
                                continue;
                        }
                }
+#endif
 
                if (pmd_bad(*pmd_dir)) {
                        printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
index 6cb1e41..0ea3756 100644 (file)
@@ -92,6 +92,8 @@ int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
        unsigned long flags, mmuar, mmutr;
        struct mm_struct *mm;
        pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        int asid;
@@ -113,7 +115,19 @@ int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
                return -1;
        }
 
-       pmd = pmd_offset(pgd, mmuar);
+       p4d = p4d_offset(pgd, mmuar);
+       if (p4d_none(*p4d)) {
+               local_irq_restore(flags);
+               return -1;
+       }
+
+       pud = pud_offset(p4d, mmuar);
+       if (pud_none(*pud)) {
+               local_irq_restore(flags);
+               return -1;
+       }
+
+       pmd = pmd_offset(pud, mmuar);
        if (pmd_none(*pmd)) {
                local_irq_restore(flags);
                return -1;
index 356601b..4857985 100644 (file)
@@ -82,9 +82,11 @@ static pmd_t * __init kernel_ptr_table(void)
                 */
                last = (unsigned long)kernel_pg_dir;
                for (i = 0; i < PTRS_PER_PGD; i++) {
-                       if (!pgd_present(kernel_pg_dir[i]))
+                       pud_t *pud = (pud_t *)(&kernel_pg_dir[i]);
+
+                       if (!pud_present(*pud))
                                continue;
-                       pmd = __pgd_page(kernel_pg_dir[i]);
+                       pmd = pgd_page_vaddr(kernel_pg_dir[i]);
                        if (pmd > last)
                                last = pmd;
                }
@@ -118,6 +120,8 @@ static void __init map_node(int node)
 #define ROOTTREESIZE (32*1024*1024)
        unsigned long physaddr, virtaddr, size;
        pgd_t *pgd_dir;
+       p4d_t *p4d_dir;
+       pud_t *pud_dir;
        pmd_t *pmd_dir;
        pte_t *pte_dir;
 
@@ -149,14 +153,16 @@ static void __init map_node(int node)
                                continue;
                        }
                }
-               if (!pgd_present(*pgd_dir)) {
+               p4d_dir = p4d_offset(pgd_dir, virtaddr);
+               pud_dir = pud_offset(p4d_dir, virtaddr);
+               if (!pud_present(*pud_dir)) {
                        pmd_dir = kernel_ptr_table();
 #ifdef DEBUG
                        printk ("[new pointer %p]", pmd_dir);
 #endif
-                       pgd_set(pgd_dir, pmd_dir);
+                       pud_set(pud_dir, pmd_dir);
                } else
-                       pmd_dir = pmd_offset(pgd_dir, virtaddr);
+                       pmd_dir = pmd_offset(pud_dir, virtaddr);
 
                if (CPU_IS_020_OR_030) {
                        if (virtaddr) {
@@ -304,4 +310,3 @@ void __init paging_init(void)
                        node_set_state(i, N_NORMAL_MEMORY);
        }
 }
-
index 89e630e..c4b8aa1 100644 (file)
@@ -80,6 +80,8 @@ inline int dvma_map_cpu(unsigned long kaddr,
                               unsigned long vaddr, int len)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
        unsigned long end;
        int ret = 0;
 
@@ -90,12 +92,14 @@ inline int dvma_map_cpu(unsigned long kaddr,
 
        pr_debug("dvma: mapping kern %08lx to virt %08lx\n", kaddr, vaddr);
        pgd = pgd_offset_k(vaddr);
+       p4d = p4d_offset(pgd, vaddr);
+       pud = pud_offset(p4d, vaddr);
 
        do {
                pmd_t *pmd;
                unsigned long end2;
 
-               if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) {
+               if((pmd = pmd_alloc(&init_mm, pud, vaddr)) == NULL) {
                        ret = -ENOMEM;
                        goto out;
                }
@@ -196,4 +200,3 @@ void dvma_unmap_iommu(unsigned long baddr, int len)
        }
 
 }
-
index d506bb0..f4b44b2 100644 (file)
@@ -90,7 +90,6 @@ typedef struct { unsigned long        pte; }          pte_t;
 typedef struct { unsigned long pgprot; }       pgprot_t;
 /* FIXME this can depend on linux kernel version */
 #   ifdef CONFIG_MMU
-typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 #   else /* CONFIG_MMU */
 typedef struct { unsigned long ste[64]; }      pmd_t;
@@ -103,7 +102,6 @@ typedef struct { p4d_t              pge[1]; }       pgd_t;
 # define pgprot_val(x) ((x).pgprot)
 
 #   ifdef CONFIG_MMU
-#   define pmd_val(x)      ((x).pmd)
 #   define pgd_val(x)      ((x).pgd)
 #   else  /* CONFIG_MMU */
 #   define pmd_val(x)  ((x).ste[0])
@@ -112,7 +110,6 @@ typedef struct { p4d_t              pge[1]; }       pgd_t;
 #   endif  /* CONFIG_MMU */
 
 # define __pte(x)      ((pte_t) { (x) })
-# define __pmd(x)      ((pmd_t) { (x) })
 # define __pgd(x)      ((pgd_t) { (x) })
 # define __pgprot(x)   ((pgprot_t) { (x) })
 
index 7ecb05b..fcf1e23 100644 (file)
@@ -41,13 +41,6 @@ static inline void free_pgd(pgd_t *pgd)
 
 #define pmd_pgtable(pmd)       pmd_page(pmd)
 
-/*
- * We don't have any real pmd's, and this code never triggers because
- * the pgd will always be present..
- */
-#define pmd_alloc_one_fast(mm, address)        ({ BUG(); ((pmd_t *)1); })
-#define pmd_alloc_one(mm, address)     ({ BUG(); ((pmd_t *)2); })
-
 extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 
 #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
@@ -58,15 +51,6 @@ extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 #define pmd_populate_kernel(mm, pmd, pte) \
                (pmd_val(*(pmd)) = (unsigned long) (pte))
 
-/*
- * We don't have any real pmd's, and this code never triggers because
- * the pgd will always be present..
- */
-#define pmd_alloc_one(mm, address)     ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(mm, x)                        do { } while (0)
-#define __pmd_free_tlb(tlb, x, addr)   pmd_free((tlb)->mm, x)
-#define pgd_populate(mm, pmd, pte)     BUG()
-
 #endif /* CONFIG_MMU */
 
 #endif /* _ASM_MICROBLAZE_PGALLOC_H */
index 954b69a..2def331 100644 (file)
@@ -59,9 +59,7 @@ extern int mem_init_done;
 
 #else /* CONFIG_MMU */
 
-#include <asm-generic/4level-fixup.h>
-
-#define __PAGETABLE_PMD_FOLDED 1
+#include <asm-generic/pgtable-nopmd.h>
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
@@ -138,13 +136,8 @@ static inline pte_t pte_mkspecial(pte_t pte)       { return pte; }
  *
  */
 
-/* PMD_SHIFT determines the size of the area mapped by the PTE pages */
-#define PMD_SHIFT      (PAGE_SHIFT + PTE_SHIFT)
-#define PMD_SIZE       (1UL << PMD_SHIFT)
-#define PMD_MASK       (~(PMD_SIZE-1))
-
 /* PGDIR_SHIFT determines what a top-level page table entry can map */
-#define PGDIR_SHIFT    PMD_SHIFT
+#define PGDIR_SHIFT    (PAGE_SHIFT + PTE_SHIFT)
 #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK     (~(PGDIR_SIZE-1))
 
@@ -165,9 +158,6 @@ static inline pte_t pte_mkspecial(pte_t pte)        { return pte; }
 #define pte_ERROR(e) \
        printk(KERN_ERR "%s:%d: bad pte "PTE_FMT".\n", \
                __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
-       printk(KERN_ERR "%s:%d: bad pmd %08lx.\n", \
-               __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
        printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \
                __FILE__, __LINE__, pgd_val(e))
@@ -314,18 +304,6 @@ extern unsigned long empty_zero_page[1024];
 
 #ifndef __ASSEMBLY__
 /*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-static inline int pgd_none(pgd_t pgd)          { return 0; }
-static inline int pgd_bad(pgd_t pgd)           { return 0; }
-static inline int pgd_present(pgd_t pgd)       { return 1; }
-#define pgd_clear(xp)                          do { } while (0)
-#define pgd_page(pgd) \
-       ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-
-/*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
@@ -479,12 +457,6 @@ static inline void ptep_mkdirty(struct mm_struct *mm,
 #define pgd_index(address)      ((address) >> PGDIR_SHIFT)
 #define pgd_offset(mm, address)         ((mm)->pgd + pgd_index(address))
 
-/* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
-{
-       return (pmd_t *) dir;
-}
-
 /* Find an entry in the third-level page table.. */
 #define pte_index(address)             \
        (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
index cdd4feb..c9125c3 100644 (file)
@@ -160,6 +160,9 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
        int err = 0, sig = ksig->sig;
        unsigned long address = 0;
 #ifdef CONFIG_MMU
+       pgd_t *pgdp;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
 #endif
@@ -195,9 +198,10 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 
        address = ((unsigned long)frame->tramp);
 #ifdef CONFIG_MMU
-       pmdp = pmd_offset(pud_offset(
-                       pgd_offset(current->mm, address),
-                                       address), address);
+       pgdp = pgd_offset(current->mm, address);
+       p4dp = p4d_offset(pgdp, address);
+       pudp = pud_offset(p4dp, address);
+       pmdp = pmd_offset(pudp, address);
 
        preempt_disable();
        ptep = pte_offset_map(pmdp, address);
index a015a95..050fc62 100644 (file)
@@ -53,8 +53,11 @@ EXPORT_SYMBOL(kmap_prot);
 
 static inline pte_t *virt_to_kpte(unsigned long vaddr)
 {
-       return pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr),
-                       vaddr), vaddr);
+       pgd_t *pgd = pgd_offset_k(vaddr);
+       p4d_t *p4d = p4d_offset(pgd, vaddr);
+       pud_t *pud = pud_offset(p4d, vaddr);
+
+       return pte_offset_kernel(pmd_offset(pud, vaddr), vaddr);
 }
 
 static void __init highmem_init(void)
index 010bb9c..68c26ca 100644 (file)
@@ -134,11 +134,16 @@ EXPORT_SYMBOL(iounmap);
 
 int map_page(unsigned long va, phys_addr_t pa, int flags)
 {
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pd;
        pte_t *pg;
        int err = -ENOMEM;
+
        /* Use upper 10 bits of VA to index the first level map */
-       pd = pmd_offset(pgd_offset_k(va), va);
+       p4d = p4d_offset(pgd_offset_k(va), va);
+       pud = pud_offset(p4d, va);
+       pd = pmd_offset(pud, va);
        /* Use middle 10 bits of VA to index the second-level map */
        pg = pte_alloc_kernel(pd, va); /* from powerpc - pgtable.c */
        /* pg = pte_alloc_kernel(&init_mm, pd, va); */
@@ -188,13 +193,17 @@ void __init mapin_ram(void)
 static int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
 {
        pgd_t   *pgd;
+       p4d_t   *p4d;
+       pud_t   *pud;
        pmd_t   *pmd;
        pte_t   *pte;
        int     retval = 0;
 
        pgd = pgd_offset(mm, addr & PAGE_MASK);
        if (pgd) {
-               pmd = pmd_offset(pgd, addr & PAGE_MASK);
+               p4d = p4d_offset(pgd, addr & PAGE_MASK);
+               pud = pud_offset(p4d, addr & PAGE_MASK);
+               pmd = pmd_offset(pud, addr & PAGE_MASK);
                if (pmd_present(*pmd)) {
                        pte = pte_offset_kernel(pmd, addr & PAGE_MASK);
                        if (pte) {
index ba8f82a..e794b2d 100644 (file)
@@ -45,13 +45,6 @@ static struct cvmx_bootmem_desc *cvmx_bootmem_desc;
 /* See header file for descriptions of functions */
 
 /**
- * This macro returns the size of a member of a structure.
- * Logically it is the same as "sizeof(s::field)" in C++, but
- * C lacks the "::" operator.
- */
-#define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field)
-
-/**
  * This macro returns a member of the
  * cvmx_bootmem_named_block_desc_t structure. These members can't
  * be directly addressed as they might be in memory not directly
@@ -65,7 +58,7 @@ static struct cvmx_bootmem_desc *cvmx_bootmem_desc;
 #define CVMX_BOOTMEM_NAMED_GET_FIELD(addr, field)                      \
        __cvmx_bootmem_desc_get(addr,                                   \
                offsetof(struct cvmx_bootmem_named_block_desc, field),  \
-               SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc, field))
+               sizeof_field(struct cvmx_bootmem_named_block_desc, field))
 
 /**
  * This function is the implementation of the get macros defined
index 9e0c2e2..128af72 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef _ASM_MSGBUF_H
 #define _ASM_MSGBUF_H
 
+#include <asm/ipcbuf.h>
 
 /*
  * The msqid64_ds structure for the MIPS architecture.
index 43e1b4a..ba7fe0c 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _ASM_SEMBUF_H
 #define _ASM_SEMBUF_H
 
+#include <asm/ipcbuf.h>
+
 /*
  * The semid64_ds structure for the MIPS architecture.
  * Note extra padding because this structure is passed back and forth
index 8feb1fa..86b3201 100644 (file)
@@ -41,17 +41,14 @@ void clear_page(void *page);
 void copy_page(void *to, void *from);
 
 typedef unsigned long pte_t;
-typedef unsigned long pmd_t;
 typedef unsigned long pgd_t;
 typedef unsigned long pgprot_t;
 
 #define pte_val(x)      (x)
-#define pmd_val(x)      (x)
 #define pgd_val(x)     (x)
 #define pgprot_val(x)   (x)
 
 #define __pte(x)        (x)
-#define __pmd(x)        (x)
 #define __pgd(x)        (x)
 #define __pgprot(x)     (x)
 
index 37125e6..85c1173 100644 (file)
@@ -15,9 +15,6 @@
 /*
  * Since we have only two-level page tables, these are trivial
  */
-#define pmd_alloc_one(mm, addr)                ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(mm, pmd)                      do { } while (0)
-#define pgd_populate(mm, pmd, pte)     BUG()
 #define pmd_pgtable(pmd) pmd_page(pmd)
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
index 6fbf251..0214e41 100644 (file)
@@ -4,8 +4,7 @@
 #ifndef _ASMNDS32_PGTABLE_H
 #define _ASMNDS32_PGTABLE_H
 
-#define __PAGETABLE_PMD_FOLDED 1
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopmd.h>
 #include <linux/sizes.h>
 
 #include <asm/memory.h>
 #ifdef CONFIG_ANDES_PAGE_SIZE_4KB
 #define PGDIR_SHIFT      22
 #define PTRS_PER_PGD     1024
-#define PMD_SHIFT        22
-#define PTRS_PER_PMD     1
 #define PTRS_PER_PTE     1024
 #endif
 
 #ifdef CONFIG_ANDES_PAGE_SIZE_8KB
 #define PGDIR_SHIFT      24
 #define PTRS_PER_PGD     256
-#define PMD_SHIFT        24
-#define PTRS_PER_PMD     1
 #define PTRS_PER_PTE     2048
 #endif
 
 #ifndef __ASSEMBLY__
 extern void __pte_error(const char *file, int line, unsigned long val);
-extern void __pmd_error(const char *file, int line, unsigned long val);
 extern void __pgd_error(const char *file, int line, unsigned long val);
 
 #define pte_ERROR(pte)         __pte_error(__FILE__, __LINE__, pte_val(pte))
-#define pmd_ERROR(pmd)         __pmd_error(__FILE__, __LINE__, pmd_val(pmd))
 #define pgd_ERROR(pgd)         __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
 #endif /* !__ASSEMBLY__ */
 
@@ -368,9 +361,6 @@ static inline pmd_t __mk_pmd(pte_t * ptep, unsigned long prot)
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(addr)      pgd_offset(&init_mm, addr)
 
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, addr)  ((pmd_t *)(dir))
-
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
        const unsigned long mask = 0xfff;
index a8aff1c..6726038 100644 (file)
@@ -7,6 +7,5 @@
 #include <asm-generic/tlb.h>
 
 #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
-#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tln)->mm, pmd)
 
 #endif
index ffa8040..e25700e 100644 (file)
@@ -14,6 +14,7 @@ unsigned int *phy_addr_sp_tmp;
 static void nds32_suspend2ram(void)
 {
        pgd_t *pgdv;
+       p4d_t *p4dv;
        pud_t *pudv;
        pmd_t *pmdv;
        pte_t *ptev;
@@ -21,7 +22,8 @@ static void nds32_suspend2ram(void)
        pgdv = (pgd_t *)__va((__nds32__mfsr(NDS32_SR_L1_PPTB) &
                L1_PPTB_mskBASE)) + pgd_index((unsigned int)cpu_resume);
 
-       pudv = pud_offset(pgdv, (unsigned int)cpu_resume);
+       p4dv = p4d_offset(pgdv, (unsigned int)cpu_resume);
+       pudv = pud_offset(p4dv, (unsigned int)cpu_resume);
        pmdv = pmd_offset(pudv, (unsigned int)cpu_resume);
        ptev = pte_offset_map(pmdv, (unsigned int)cpu_resume);
 
index 064ae5d..906dfb2 100644 (file)
@@ -31,6 +31,8 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
        pr_alert("[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
 
        do {
+               p4d_t *p4d;
+               pud_t *pud;
                pmd_t *pmd;
 
                if (pgd_none(*pgd))
@@ -41,7 +43,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
                        break;
                }
 
-               pmd = pmd_offset(pgd, addr);
+               p4d = p4d_offset(pgd, addr);
+               pud = pud_offset(p4d, addr);
+               pmd = pmd_offset(pud, addr);
 #if PTRS_PER_PMD != 1
                pr_alert(", *pmd=%08lx", pmd_val(*pmd));
 #endif
@@ -359,6 +363,7 @@ vmalloc_fault:
 
                unsigned int index = pgd_index(addr);
                pgd_t *pgd, *pgd_k;
+               p4d_t *p4d, *p4d_k;
                pud_t *pud, *pud_k;
                pmd_t *pmd, *pmd_k;
                pte_t *pte_k;
@@ -369,8 +374,13 @@ vmalloc_fault:
                if (!pgd_present(*pgd_k))
                        goto no_context;
 
-               pud = pud_offset(pgd, addr);
-               pud_k = pud_offset(pgd_k, addr);
+               p4d = p4d_offset(pgd, addr);
+               p4d_k = p4d_offset(pgd_k, addr);
+               if (!p4d_present(*p4d_k))
+                       goto no_context;
+
+               pud = pud_offset(p4d, addr);
+               pud_k = pud_offset(p4d_k, addr);
                if (!pud_present(*pud_k))
                        goto no_context;
 
index 55703b0..0be3833 100644 (file)
@@ -54,6 +54,7 @@ static void __init map_ram(void)
 {
        unsigned long v, p, e;
        pgd_t *pge;
+       p4d_t *p4e;
        pud_t *pue;
        pmd_t *pme;
        pte_t *pte;
@@ -69,7 +70,8 @@ static void __init map_ram(void)
 
        while (p < e) {
                int j;
-               pue = pud_offset(pge, v);
+               p4e = p4d_offset(pge, v);
+               pue = pud_offset(p4e, v);
                pme = pmd_offset(pue, v);
 
                if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) {
@@ -100,6 +102,7 @@ static void __init fixedrange_init(void)
 {
        unsigned long vaddr;
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
 #ifdef CONFIG_HIGHMEM
@@ -111,7 +114,8 @@ static void __init fixedrange_init(void)
         */
        vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
        pgd = swapper_pg_dir + pgd_index(vaddr);
-       pud = pud_offset(pgd, vaddr);
+       p4d = p4d_offset(pgd, vaddr);
+       pud = pud_offset(p4d, vaddr);
        pmd = pmd_offset(pud, vaddr);
        fixmap_pmd_p = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
        if (!fixmap_pmd_p)
@@ -126,7 +130,8 @@ static void __init fixedrange_init(void)
        vaddr = PKMAP_BASE;
 
        pgd = swapper_pg_dir + pgd_index(vaddr);
-       pud = pud_offset(pgd, vaddr);
+       p4d = p4d_offset(pgd, vaddr);
+       pud = pud_offset(p4d, vaddr);
        pmd = pmd_offset(pud, vaddr);
        pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
        if (!pte)
index 3b43798..8503bee 100644 (file)
@@ -74,6 +74,8 @@ void setup_mm_for_reboot(char mode)
 {
        unsigned long pmdval;
        pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pmd;
        int i;
 
@@ -84,7 +86,9 @@ void setup_mm_for_reboot(char mode)
 
        for (i = 0; i < USER_PTRS_PER_PGD; i++) {
                pmdval = (i << PGDIR_SHIFT);
-               pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
+               p4d = p4d_offset(pgd, i << PGDIR_SHIFT);
+               pud = pud_offset(p4d, i << PGDIR_SHIFT);
+               pmd = pmd_offset(pud + i, i << PGDIR_SHIFT);
                set_pmd(pmd, __pmd(pmdval));
        }
 }
index ba80992..837ae77 100644 (file)
@@ -16,10 +16,14 @@ extern struct cache_info L1_cache_info[2];
 
 int va_kernel_present(unsigned long addr)
 {
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *ptep, pte;
 
-       pmd = pmd_offset(pgd_offset_k(addr), addr);
+       p4d = p4d_offset(pgd_offset_k(addr), addr);
+       pud = pud_offset(p4d, addr);
+       pmd = pmd_offset(pud, addr);
        if (!pmd_none(*pmd)) {
                ptep = pte_offset_map(pmd, addr);
                pte = *ptep;
@@ -32,20 +36,24 @@ int va_kernel_present(unsigned long addr)
 pte_t va_present(struct mm_struct * mm, unsigned long addr)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *ptep, pte;
 
        pgd = pgd_offset(mm, addr);
        if (!pgd_none(*pgd)) {
-               pud = pud_offset(pgd, addr);
-               if (!pud_none(*pud)) {
-                       pmd = pmd_offset(pud, addr);
-                       if (!pmd_none(*pmd)) {
-                               ptep = pte_offset_map(pmd, addr);
-                               pte = *ptep;
-                               if (pte_present(pte))
-                                       return pte;
+               p4d = p4d_offset(pgd, addr);
+               if (!p4d_none(*p4d)) {
+                       pud = pud_offset(p4d, addr);
+                       if (!pud_none(*pud)) {
+                               pmd = pmd_offset(pud, addr);
+                               if (!pmd_none(*pmd)) {
+                                       ptep = pte_offset_map(pmd, addr);
+                                       pte = *ptep;
+                                       if (pte_present(pte))
+                                               return pte;
+                               }
                        }
                }
        }
index b56af75..819bdfc 100644 (file)
@@ -138,6 +138,14 @@ void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
                                return NULL;
        }
 
+       /*
+        * Map uncached objects in the low part of address space to
+        * CONFIG_NIOS2_IO_REGION_BASE
+        */
+       if (IS_MAPPABLE_UNCACHEABLE(phys_addr) &&
+           IS_MAPPABLE_UNCACHEABLE(last_addr))
+               return (void __iomem *)(CONFIG_NIOS2_IO_REGION_BASE + phys_addr);
+
        /* Mappings have to be page-aligned */
        offset = phys_addr & ~PAGE_MASK;
        phys_addr &= PAGE_MASK;
index 93caf17..796ae29 100644 (file)
@@ -42,48 +42,54 @@ typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */
 
 /* NOTE: even on 64 bits, these entries are __u32 because we allocate
  * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
-typedef struct { __u32 pmd; } pmd_t;
 typedef struct { __u32 pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x)     ((x).pte)
-/* These do not work lvalues, so make sure we don't use them as such. */
+#if CONFIG_PGTABLE_LEVELS == 3
+typedef struct { __u32 pmd; } pmd_t;
+#define __pmd(x)       ((pmd_t) { (x) } )
+/* pXd_val() do not work as lvalues, so make sure we don't use them as such. */
 #define pmd_val(x)     ((x).pmd + 0)
+#endif
+
+#define pte_val(x)     ((x).pte)
 #define pgd_val(x)     ((x).pgd + 0)
 #define pgprot_val(x)  ((x).pgprot)
 
 #define __pte(x)       ((pte_t) { (x) } )
-#define __pmd(x)       ((pmd_t) { (x) } )
 #define __pgd(x)       ((pgd_t) { (x) } )
 #define __pgprot(x)    ((pgprot_t) { (x) } )
 
-#define __pmd_val_set(x,n) (x).pmd = (n)
-#define __pgd_val_set(x,n) (x).pgd = (n)
-
 #else
 /*
  * .. while these make it easier on the compiler
  */
 typedef unsigned long pte_t;
+
+#if CONFIG_PGTABLE_LEVELS == 3
 typedef         __u32 pmd_t;
+#define pmd_val(x)      (x)
+#define __pmd(x)       (x)
+#endif
+
 typedef         __u32 pgd_t;
 typedef unsigned long pgprot_t;
 
 #define pte_val(x)      (x)
-#define pmd_val(x)      (x)
 #define pgd_val(x)      (x)
 #define pgprot_val(x)   (x)
 
 #define __pte(x)        (x)
-#define __pmd(x)       (x)
 #define __pgd(x)        (x)
 #define __pgprot(x)     (x)
 
-#define __pmd_val_set(x,n) (x) = (n)
-#define __pgd_val_set(x,n) (x) = (n)
-
 #endif /* STRICT_MM_TYPECHECKS */
 
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
+#if CONFIG_PGTABLE_LEVELS == 3
+#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
+#endif
+
 typedef struct page *pgtable_t;
 
 typedef struct __physmem_range {
index d98647c..9ac74da 100644 (file)
@@ -34,13 +34,13 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
                /* Populate first pmd with allocated memory.  We mark it
                 * with PxD_FLAG_ATTACHED as a signal to the system that this
                 * pmd entry may not be cleared. */
-               __pgd_val_set(*actual_pgd, (PxD_FLAG_PRESENT | 
-                                       PxD_FLAG_VALID | 
-                                       PxD_FLAG_ATTACHED) 
-                       + (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT));
+               set_pgd(actual_pgd, __pgd((PxD_FLAG_PRESENT |
+                                       PxD_FLAG_VALID |
+                                       PxD_FLAG_ATTACHED)
+                       + (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT)));
                /* The first pmd entry also is marked with PxD_FLAG_ATTACHED as
                 * a signal that this pmd may not be freed */
-               __pgd_val_set(*pgd, PxD_FLAG_ATTACHED);
+               set_pgd(pgd, __pgd(PxD_FLAG_ATTACHED));
 #endif
        }
        spin_lock_init(pgd_spinlock(actual_pgd));
@@ -59,10 +59,10 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 /* Three Level Page Table Support for pmd's */
 
-static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
-       __pgd_val_set(*pgd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
-                       (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT));
+       set_pud(pud, __pud((PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
+                       (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
 }
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
@@ -88,19 +88,6 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
        free_pages((unsigned long)pmd, PMD_ORDER);
 }
 
-#else
-
-/* Two Level Page Table Support for pmd's */
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-
-#define pmd_alloc_one(mm, addr)                ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(mm, x)                        do { } while (0)
-#define pgd_populate(mm, pmd, pte)     BUG()
-
 #endif
 
 static inline void
@@ -110,14 +97,14 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
        /* preserve the gateway marker if this is the beginning of
         * the permanent pmd */
        if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
-               __pmd_val_set(*pmd, (PxD_FLAG_PRESENT |
-                                PxD_FLAG_VALID |
-                                PxD_FLAG_ATTACHED) 
-                       + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
+               set_pmd(pmd, __pmd((PxD_FLAG_PRESENT |
+                               PxD_FLAG_VALID |
+                               PxD_FLAG_ATTACHED)
+                       + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
        else
 #endif
-               __pmd_val_set(*pmd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID) 
-                       + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
+               set_pmd(pmd, __pmd((PxD_FLAG_PRESENT | PxD_FLAG_VALID)
+                       + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
 }
 
 #define pmd_populate(mm, pmd, pte_page) \
index 4ac374b..f0a3659 100644 (file)
@@ -3,7 +3,12 @@
 #define _PARISC_PGTABLE_H
 
 #include <asm/page.h>
-#include <asm-generic/4level-fixup.h>
+
+#if CONFIG_PGTABLE_LEVELS == 3
+#include <asm-generic/pgtable-nopud.h>
+#elif CONFIG_PGTABLE_LEVELS == 2
+#include <asm-generic/pgtable-nopmd.h>
+#endif
 
 #include <asm/fixmap.h>
 
@@ -101,8 +106,10 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
 
 #define pte_ERROR(e) \
        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#if CONFIG_PGTABLE_LEVELS == 3
 #define pmd_ERROR(e) \
        printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, (unsigned long)pmd_val(e))
+#endif
 #define pgd_ERROR(e) \
        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
 
@@ -132,19 +139,18 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
 #define PTRS_PER_PTE    (1UL << BITS_PER_PTE)
 
 /* Definitions for 2nd level */
+#if CONFIG_PGTABLE_LEVELS == 3
 #define PMD_SHIFT       (PLD_SHIFT + BITS_PER_PTE)
 #define PMD_SIZE       (1UL << PMD_SHIFT)
 #define PMD_MASK       (~(PMD_SIZE-1))
-#if CONFIG_PGTABLE_LEVELS == 3
 #define BITS_PER_PMD   (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY)
+#define PTRS_PER_PMD    (1UL << BITS_PER_PMD)
 #else
-#define __PAGETABLE_PMD_FOLDED 1
 #define BITS_PER_PMD   0
 #endif
-#define PTRS_PER_PMD    (1UL << BITS_PER_PMD)
 
 /* Definitions for 1st level */
-#define PGDIR_SHIFT    (PMD_SHIFT + BITS_PER_PMD)
+#define PGDIR_SHIFT    (PLD_SHIFT + BITS_PER_PTE + BITS_PER_PMD)
 #if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG
 #define BITS_PER_PGD   (BITS_PER_LONG - PGDIR_SHIFT)
 #else
@@ -317,6 +323,8 @@ extern unsigned long *empty_zero_page;
 
 #define pmd_flag(x)    (pmd_val(x) & PxD_FLAG_MASK)
 #define pmd_address(x) ((unsigned long)(pmd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
+#define pud_flag(x)    (pud_val(x) & PxD_FLAG_MASK)
+#define pud_address(x) ((unsigned long)(pud_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
 #define pgd_flag(x)    (pgd_val(x) & PxD_FLAG_MASK)
 #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
 
@@ -334,42 +342,32 @@ static inline void pmd_clear(pmd_t *pmd) {
        if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
                /* This is the entry pointing to the permanent pmd
                 * attached to the pgd; cannot clear it */
-               __pmd_val_set(*pmd, PxD_FLAG_ATTACHED);
+               set_pmd(pmd, __pmd(PxD_FLAG_ATTACHED));
        else
 #endif
-               __pmd_val_set(*pmd,  0);
+               set_pmd(pmd,  __pmd(0));
 }
 
 
 
 #if CONFIG_PGTABLE_LEVELS == 3
-#define pgd_page_vaddr(pgd) ((unsigned long) __va(pgd_address(pgd)))
-#define pgd_page(pgd)  virt_to_page((void *)pgd_page_vaddr(pgd))
+#define pud_page_vaddr(pud) ((unsigned long) __va(pud_address(pud)))
+#define pud_page(pud)  virt_to_page((void *)pud_page_vaddr(pud))
 
 /* For 64 bit we have three level tables */
 
-#define pgd_none(x)     (!pgd_val(x))
-#define pgd_bad(x)      (!(pgd_flag(x) & PxD_FLAG_VALID))
-#define pgd_present(x)  (pgd_flag(x) & PxD_FLAG_PRESENT)
-static inline void pgd_clear(pgd_t *pgd) {
+#define pud_none(x)     (!pud_val(x))
+#define pud_bad(x)      (!(pud_flag(x) & PxD_FLAG_VALID))
+#define pud_present(x)  (pud_flag(x) & PxD_FLAG_PRESENT)
+static inline void pud_clear(pud_t *pud) {
 #if CONFIG_PGTABLE_LEVELS == 3
-       if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED)
-               /* This is the permanent pmd attached to the pgd; cannot
+       if(pud_flag(*pud) & PxD_FLAG_ATTACHED)
+               /* This is the permanent pmd attached to the pud; cannot
                 * free it */
                return;
 #endif
-       __pgd_val_set(*pgd, 0);
+       set_pud(pud, __pud(0));
 }
-#else
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-static inline int pgd_none(pgd_t pgd)          { return 0; }
-static inline int pgd_bad(pgd_t pgd)           { return 0; }
-static inline int pgd_present(pgd_t pgd)       { return 1; }
-static inline void pgd_clear(pgd_t * pgdp)     { }
 #endif
 
 /*
@@ -452,7 +450,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #if CONFIG_PGTABLE_LEVELS == 3
 #define pmd_index(addr)         (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 #define pmd_offset(dir,address) \
-((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(address))
+((pmd_t *) pud_page_vaddr(*(dir)) + pmd_index(address))
 #else
 #define pmd_offset(dir,addr) ((pmd_t *) dir)
 #endif
index 8c0446b..44235f3 100644 (file)
@@ -4,7 +4,9 @@
 
 #include <asm-generic/tlb.h>
 
+#if CONFIG_PGTABLE_LEVELS == 3
 #define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
+#endif
 #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
 
 #endif
index 3b87733..3b4de5b 100644 (file)
@@ -3,6 +3,7 @@
 #define _PARISC_MSGBUF_H
 
 #include <asm/bitsperlong.h>
+#include <asm/ipcbuf.h>
 
 /* 
  * The msqid64_ds structure for parisc architecture, copied from sparc.
index 8241cf1..e2ca430 100644 (file)
@@ -3,6 +3,7 @@
 #define _PARISC_SEMBUF_H
 
 #include <asm/bitsperlong.h>
+#include <asm/ipcbuf.h>
 
 /* 
  * The semid64_ds structure for parisc architecture.
index 2407b0b..1eedfec 100644 (file)
@@ -534,11 +534,14 @@ static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr)
        pte_t *ptep = NULL;
 
        if (!pgd_none(*pgd)) {
-               pud_t *pud = pud_offset(pgd, addr);
-               if (!pud_none(*pud)) {
-                       pmd_t *pmd = pmd_offset(pud, addr);
-                       if (!pmd_none(*pmd))
-                               ptep = pte_offset_map(pmd, addr);
+               p4d_t *p4d = p4d_offset(pgd, addr);
+               if (!p4d_none(*p4d)) {
+                       pud_t *pud = pud_offset(p4d, addr);
+                       if (!pud_none(*pud)) {
+                               pmd_t *pmd = pmd_offset(pud, addr);
+                               if (!pmd_none(*pmd))
+                                       ptep = pte_offset_map(pmd, addr);
+                       }
                }
        }
        return ptep;
index a60d47f..0f1b460 100644 (file)
@@ -133,9 +133,14 @@ static inline int map_uncached_pages(unsigned long vaddr, unsigned long size,
 
        dir = pgd_offset_k(vaddr);
        do {
+               p4d_t *p4d;
+               pud_t *pud;
                pmd_t *pmd;
-               
-               pmd = pmd_alloc(NULL, dir, vaddr);
+
+               p4d = p4d_offset(dir, vaddr);
+               pud = pud_offset(p4d, vaddr);
+               pmd = pmd_alloc(NULL, pud, vaddr);
+
                if (!pmd)
                        return -ENOMEM;
                if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))
index 474cd24..e2d8b0a 100644 (file)
@@ -14,11 +14,13 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
 {
        unsigned long vaddr = __fix_to_virt(idx);
        pgd_t *pgd = pgd_offset_k(vaddr);
-       pmd_t *pmd = pmd_offset(pgd, vaddr);
+       p4d_t *p4d = p4d_offset(pgd, vaddr);
+       pud_t *pud = pud_offset(p4d, vaddr);
+       pmd_t *pmd = pmd_offset(pud, vaddr);
        pte_t *pte;
 
        if (pmd_none(*pmd))
-               pmd = pmd_alloc(NULL, pgd, vaddr);
+               pmd = pmd_alloc(NULL, pud, vaddr);
 
        pte = pte_offset_kernel(pmd, vaddr);
        if (pte_none(*pte))
@@ -32,7 +34,9 @@ void notrace clear_fixmap(enum fixed_addresses idx)
 {
        unsigned long vaddr = __fix_to_virt(idx);
        pgd_t *pgd = pgd_offset_k(vaddr);
-       pmd_t *pmd = pmd_offset(pgd, vaddr);
+       p4d_t *p4d = p4d_offset(pgd, vaddr);
+       pud_t *pud = pud_offset(p4d, vaddr);
+       pmd_t *pmd = pmd_offset(pud, vaddr);
        pte_t *pte = pte_offset_kernel(pmd, vaddr);
 
        if (WARN_ON(pte_none(*pte)))
index d578809..0e1e212 100644 (file)
@@ -49,6 +49,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
                        unsigned long addr, unsigned long sz)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte = NULL;
@@ -61,7 +62,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
        addr &= HPAGE_MASK;
 
        pgd = pgd_offset(mm, addr);
-       pud = pud_alloc(mm, pgd, addr);
+       p4d = p4d_offset(pgd, addr);
+       pud = pud_alloc(mm, p4d, addr);
        if (pud) {
                pmd = pmd_alloc(mm, pud, addr);
                if (pmd)
@@ -74,6 +76,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
                       unsigned long addr, unsigned long sz)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte = NULL;
@@ -82,11 +85,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
 
        pgd = pgd_offset(mm, addr);
        if (!pgd_none(*pgd)) {
-               pud = pud_offset(pgd, addr);
-               if (!pud_none(*pud)) {
-                       pmd = pmd_offset(pud, addr);
-                       if (!pmd_none(*pmd))
-                               pte = pte_offset_map(pmd, addr);
+               p4d = p4d_offset(pgd, addr);
+               if (!p4d_none(*p4d)) {
+                       pud = pud_offset(p4d, addr);
+                       if (!pud_none(*pud)) {
+                               pmd = pmd_offset(pud, addr);
+                               if (!pmd_none(*pmd))
+                                       pte = pte_offset_map(pmd, addr);
+                       }
                }
        }
        return pte;
index e446bb5..1ec34e1 100644 (file)
@@ -452,6 +452,23 @@ config PPC_TRANSACTIONAL_MEM
        help
          Support user-mode Transactional Memory on POWERPC.
 
+config PPC_UV
+       bool "Ultravisor support"
+       depends on KVM_BOOK3S_HV_POSSIBLE
+       select ZONE_DEVICE
+       select DEV_PAGEMAP_OPS
+       select DEVICE_PRIVATE
+       select MEMORY_HOTPLUG
+       select MEMORY_HOTREMOVE
+       default n
+       help
+         This option paravirtualizes the kernel to run in POWER platforms that
+         supports the Protected Execution Facility (PEF). On such platforms,
+         the ultravisor firmware runs at a privilege level above the
+         hypervisor.
+
+         If unsure, say "N".
+
 config LD_HEAD_STUB_CATCH
        bool "Reserve 256 bytes to cope with linker stubs in HEAD text" if EXPERT
        depends on PPC64
index 9c63b59..a09595f 100644 (file)
@@ -28,7 +28,7 @@ static inline int arch_get_random_seed_int(unsigned int *v)
        unsigned long val;
        int rc;
 
-       rc = arch_get_random_long(&val);
+       rc = arch_get_random_seed_long(&val);
        if (rc)
                *v = val;
 
index 603aed2..28dcf82 100644 (file)
@@ -64,7 +64,7 @@
 
 /* Macro for generating the ***_bits() functions */
 #define DEFINE_BITOP(fn, op, prefix)           \
-static __inline__ void fn(unsigned long mask,  \
+static inline void fn(unsigned long mask,      \
                volatile unsigned long *_p)     \
 {                                              \
        unsigned long old;                      \
@@ -86,22 +86,22 @@ DEFINE_BITOP(clear_bits, andc, "")
 DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER)
 DEFINE_BITOP(change_bits, xor, "")
 
-static __inline__ void set_bit(int nr, volatile unsigned long *addr)
+static inline void arch_set_bit(int nr, volatile unsigned long *addr)
 {
        set_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
 
-static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
+static inline void arch_clear_bit(int nr, volatile unsigned long *addr)
 {
        clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
 
-static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
+static inline void arch_clear_bit_unlock(int nr, volatile unsigned long *addr)
 {
        clear_bits_unlock(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
 
-static __inline__ void change_bit(int nr, volatile unsigned long *addr)
+static inline void arch_change_bit(int nr, volatile unsigned long *addr)
 {
        change_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
 }
@@ -109,7 +109,7 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr)
 /* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
  * operands. */
 #define DEFINE_TESTOP(fn, op, prefix, postfix, eh)     \
-static __inline__ unsigned long fn(                    \
+static inline unsigned long fn(                        \
                unsigned long mask,                     \
                volatile unsigned long *_p)             \
 {                                                      \
@@ -138,34 +138,34 @@ DEFINE_TESTOP(test_and_clear_bits, andc, PPC_ATOMIC_ENTRY_BARRIER,
 DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER,
              PPC_ATOMIC_EXIT_BARRIER, 0)
 
-static __inline__ int test_and_set_bit(unsigned long nr,
-                                      volatile unsigned long *addr)
+static inline int arch_test_and_set_bit(unsigned long nr,
+                                       volatile unsigned long *addr)
 {
        return test_and_set_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
 }
 
-static __inline__ int test_and_set_bit_lock(unsigned long nr,
-                                      volatile unsigned long *addr)
+static inline int arch_test_and_set_bit_lock(unsigned long nr,
+                                            volatile unsigned long *addr)
 {
        return test_and_set_bits_lock(BIT_MASK(nr),
                                addr + BIT_WORD(nr)) != 0;
 }
 
-static __inline__ int test_and_clear_bit(unsigned long nr,
-                                        volatile unsigned long *addr)
+static inline int arch_test_and_clear_bit(unsigned long nr,
+                                         volatile unsigned long *addr)
 {
        return test_and_clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
 }
 
-static __inline__ int test_and_change_bit(unsigned long nr,
-                                         volatile unsigned long *addr)
+static inline int arch_test_and_change_bit(unsigned long nr,
+                                          volatile unsigned long *addr)
 {
        return test_and_change_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
 }
 
 #ifdef CONFIG_PPC64
-static __inline__ unsigned long clear_bit_unlock_return_word(int nr,
-                                               volatile unsigned long *addr)
+static inline unsigned long
+clear_bit_unlock_return_word(int nr, volatile unsigned long *addr)
 {
        unsigned long old, t;
        unsigned long *p = (unsigned long *)addr + BIT_WORD(nr);
@@ -185,15 +185,18 @@ static __inline__ unsigned long clear_bit_unlock_return_word(int nr,
        return old;
 }
 
-/* This is a special function for mm/filemap.c */
-#define clear_bit_unlock_is_negative_byte(nr, addr)                    \
-       (clear_bit_unlock_return_word(nr, addr) & BIT_MASK(PG_waiters))
+/*
+ * This is a special function for mm/filemap.c
+ * Bit 7 corresponds to PG_waiters.
+ */
+#define arch_clear_bit_unlock_is_negative_byte(nr, addr)               \
+       (clear_bit_unlock_return_word(nr, addr) & BIT_MASK(7))
 
 #endif /* CONFIG_PPC64 */
 
 #include <asm-generic/bitops/non-atomic.h>
 
-static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
+static inline void arch___clear_bit_unlock(int nr, volatile unsigned long *addr)
 {
        __asm__ __volatile__(PPC_RELEASE_BARRIER "" ::: "memory");
        __clear_bit(nr, addr);
@@ -215,14 +218,14 @@ static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
  * fls: find last (most-significant) bit set.
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static __inline__ int fls(unsigned int x)
+static inline int fls(unsigned int x)
 {
        return 32 - __builtin_clz(x);
 }
 
 #include <asm-generic/bitops/builtin-__fls.h>
 
-static __inline__ int fls64(__u64 x)
+static inline int fls64(__u64 x)
 {
        return 64 - __builtin_clzll(x);
 }
@@ -239,6 +242,10 @@ unsigned long __arch_hweight64(__u64 w);
 
 #include <asm-generic/bitops/find.h>
 
+/* wrappers that deal with KASAN instrumentation */
+#include <asm-generic/bitops/instrumented-atomic.h>
+#include <asm-generic/bitops/instrumented-lock.h>
+
 /* Little-endian versions */
 #include <asm-generic/bitops/le.h>
 
index 1111202..13bd870 100644 (file)
 #define H_TLB_INVALIDATE       0xF808
 #define H_COPY_TOFROM_GUEST    0xF80C
 
+/* Flags for H_SVM_PAGE_IN */
+#define H_PAGE_IN_SHARED        0x1
+
+/* Platform-specific hcalls used by the Ultravisor */
+#define H_SVM_PAGE_IN          0xEF00
+#define H_SVM_PAGE_OUT         0xEF04
+#define H_SVM_INIT_START       0xEF08
+#define H_SVM_INIT_DONE                0xEF0C
+
 /* Values for 2nd argument to H_SET_MODE */
 #define H_SET_MODE_RESOURCE_SET_CIABR          1
 #define H_SET_MODE_RESOURCE_SET_DAWR           2
diff --git a/arch/powerpc/include/asm/kvm_book3s_uvmem.h b/arch/powerpc/include/asm/kvm_book3s_uvmem.h
new file mode 100644 (file)
index 0000000..50204e2
--- /dev/null
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_KVM_BOOK3S_UVMEM_H__
+#define __ASM_KVM_BOOK3S_UVMEM_H__
+
+#ifdef CONFIG_PPC_UV
+int kvmppc_uvmem_init(void);
+void kvmppc_uvmem_free(void);
+int kvmppc_uvmem_slot_init(struct kvm *kvm, const struct kvm_memory_slot *slot);
+void kvmppc_uvmem_slot_free(struct kvm *kvm,
+                           const struct kvm_memory_slot *slot);
+unsigned long kvmppc_h_svm_page_in(struct kvm *kvm,
+                                  unsigned long gra,
+                                  unsigned long flags,
+                                  unsigned long page_shift);
+unsigned long kvmppc_h_svm_page_out(struct kvm *kvm,
+                                   unsigned long gra,
+                                   unsigned long flags,
+                                   unsigned long page_shift);
+unsigned long kvmppc_h_svm_init_start(struct kvm *kvm);
+unsigned long kvmppc_h_svm_init_done(struct kvm *kvm);
+int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn);
+void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
+                            struct kvm *kvm);
+#else
+static inline int kvmppc_uvmem_init(void)
+{
+       return 0;
+}
+
+static inline void kvmppc_uvmem_free(void) { }
+
+static inline int
+kvmppc_uvmem_slot_init(struct kvm *kvm, const struct kvm_memory_slot *slot)
+{
+       return 0;
+}
+
+static inline void
+kvmppc_uvmem_slot_free(struct kvm *kvm, const struct kvm_memory_slot *slot) { }
+
+static inline unsigned long
+kvmppc_h_svm_page_in(struct kvm *kvm, unsigned long gra,
+                    unsigned long flags, unsigned long page_shift)
+{
+       return H_UNSUPPORTED;
+}
+
+static inline unsigned long
+kvmppc_h_svm_page_out(struct kvm *kvm, unsigned long gra,
+                     unsigned long flags, unsigned long page_shift)
+{
+       return H_UNSUPPORTED;
+}
+
+static inline unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
+{
+       return H_UNSUPPORTED;
+}
+
+static inline unsigned long kvmppc_h_svm_init_done(struct kvm *kvm)
+{
+       return H_UNSUPPORTED;
+}
+
+static inline int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn)
+{
+       return -EFAULT;
+}
+
+static inline void
+kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
+                       struct kvm *kvm) { }
+#endif /* CONFIG_PPC_UV */
+#endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */
index 4273e79..0a398f2 100644 (file)
@@ -275,6 +275,10 @@ struct kvm_hpt_info {
 
 struct kvm_resize_hpt;
 
+/* Flag values for kvm_arch.secure_guest */
+#define KVMPPC_SECURE_INIT_START 0x1 /* H_SVM_INIT_START has been called */
+#define KVMPPC_SECURE_INIT_DONE  0x2 /* H_SVM_INIT_DONE completed */
+
 struct kvm_arch {
        unsigned int lpid;
        unsigned int smt_mode;          /* # vcpus per virtual core */
@@ -330,6 +334,8 @@ struct kvm_arch {
 #endif
        struct kvmppc_ops *kvm_ops;
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+       struct mutex uvmem_lock;
+       struct list_head uvmem_pfns;
        struct mutex mmu_setup_lock;    /* nests inside vcpu mutexes */
        u64 l1_ptcr;
        int max_nested_lpid;
index d63f649..3d2f871 100644 (file)
@@ -322,6 +322,7 @@ struct kvmppc_ops {
                               int size);
        int (*store_to_eaddr)(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
                              int size);
+       int (*svm_off)(struct kvm *kvm);
 };
 
 extern struct kvmppc_ops *kvmppc_hv_ops;
index 4fcda1d..b66f6db 100644 (file)
 #define UV_WRITE_PATE                  0xF104
 #define UV_RETURN                      0xF11C
 #define UV_ESM                         0xF110
+#define UV_REGISTER_MEM_SLOT           0xF120
+#define UV_UNREGISTER_MEM_SLOT         0xF124
+#define UV_PAGE_IN                     0xF128
+#define UV_PAGE_OUT                    0xF12C
 #define UV_SHARE_PAGE                  0xF130
 #define UV_UNSHARE_PAGE                        0xF134
 #define UV_UNSHARE_ALL_PAGES           0xF140
+#define UV_PAGE_INVAL                  0xF138
+#define UV_SVM_TERMINATE               0xF13C
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
index b1bc2e0..790b0e6 100644 (file)
@@ -46,4 +46,40 @@ static inline int uv_unshare_all_pages(void)
        return ucall_norets(UV_UNSHARE_ALL_PAGES);
 }
 
+static inline int uv_page_in(u64 lpid, u64 src_ra, u64 dst_gpa, u64 flags,
+                            u64 page_shift)
+{
+       return ucall_norets(UV_PAGE_IN, lpid, src_ra, dst_gpa, flags,
+                           page_shift);
+}
+
+static inline int uv_page_out(u64 lpid, u64 dst_ra, u64 src_gpa, u64 flags,
+                             u64 page_shift)
+{
+       return ucall_norets(UV_PAGE_OUT, lpid, dst_ra, src_gpa, flags,
+                           page_shift);
+}
+
+static inline int uv_register_mem_slot(u64 lpid, u64 start_gpa, u64 size,
+                                      u64 flags, u64 slotid)
+{
+       return ucall_norets(UV_REGISTER_MEM_SLOT, lpid, start_gpa,
+                           size, flags, slotid);
+}
+
+static inline int uv_unregister_mem_slot(u64 lpid, u64 slotid)
+{
+       return ucall_norets(UV_UNREGISTER_MEM_SLOT, lpid, slotid);
+}
+
+static inline int uv_page_inval(u64 lpid, u64 gpa, u64 page_shift)
+{
+       return ucall_norets(UV_PAGE_INVAL, lpid, gpa, page_shift);
+}
+
+static inline int uv_svm_terminate(u64 lpid)
+{
+       return ucall_norets(UV_SVM_TERMINATE, lpid);
+}
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
index a115970..40f13f3 100644 (file)
@@ -83,6 +83,7 @@ struct vdso_data {
        __s64 wtom_clock_sec;                   /* Wall to monotonic clock sec */
        __s64 stamp_xtime_sec;                  /* xtime secs as at tb_orig_stamp */
        __s64 stamp_xtime_nsec;                 /* xtime nsecs as at tb_orig_stamp */
+       __u32 hrtimer_res;                      /* hrtimer resolution */
        __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls  */
        __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
 };
@@ -105,6 +106,7 @@ struct vdso_data {
        __s32 stamp_xtime_sec;          /* xtime seconds as at tb_orig_stamp */
        __s32 stamp_xtime_nsec;         /* xtime nsecs as at tb_orig_stamp */
        __u32 stamp_sec_fraction;       /* fractional seconds of stamp_xtime */
+       __u32 hrtimer_res;              /* hrtimer resolution */
        __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
        __u32 dcache_block_size;        /* L1 d-cache block size     */
        __u32 icache_block_size;        /* L1 i-cache block size     */
index 969bd83..7919b2b 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _ASM_POWERPC_MSGBUF_H
 #define _ASM_POWERPC_MSGBUF_H
 
+#include <asm/ipcbuf.h>
+
 /*
  * The msqid64_ds structure for the PowerPC architecture.
  * Note extra padding because this structure is passed back and forth
index 008ae77..85e96cc 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _ASM_POWERPC_SEMBUF_H
 #define _ASM_POWERPC_SEMBUF_H
 
+#include <asm/ipcbuf.h>
+
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
index f22bd6d..3d47aec 100644 (file)
@@ -388,6 +388,7 @@ int main(void)
        OFFSET(STAMP_XTIME_SEC, vdso_data, stamp_xtime_sec);
        OFFSET(STAMP_XTIME_NSEC, vdso_data, stamp_xtime_nsec);
        OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction);
+       OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res);
        OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size);
        OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size);
        OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size);
@@ -413,7 +414,6 @@ int main(void)
        DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
        DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
        DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
-       DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
 
 #ifdef CONFIG_BUG
        DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
index 838d9d4..6f7a3a7 100644 (file)
@@ -240,6 +240,9 @@ set_ivor:
 
        bl      early_init
 
+#ifdef CONFIG_KASAN
+       bl      kasan_early_init
+#endif
 #ifdef CONFIG_RELOCATABLE
        mr      r3,r30
        mr      r4,r31
@@ -266,9 +269,6 @@ set_ivor:
 /*
  * Decide what sort of machine this is and initialize the MMU.
  */
-#ifdef CONFIG_KASAN
-       bl      kasan_early_init
-#endif
        mr      r3,r30
        mr      r4,r31
        bl      machine_init
index 2d13cea..1168e8b 100644 (file)
@@ -960,6 +960,7 @@ void update_vsyscall(struct timekeeper *tk)
        vdso_data->stamp_xtime_sec = xt.tv_sec;
        vdso_data->stamp_xtime_nsec = xt.tv_nsec;
        vdso_data->stamp_sec_fraction = frac_sec;
+       vdso_data->hrtimer_res = hrtimer_resolution;
        smp_wmb();
        ++(vdso_data->tb_update_count);
 }
index c8e6902..3306672 100644 (file)
@@ -154,12 +154,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
        cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
+       mflr    r12
+  .cfi_register lr,r12
+       bl      __get_datapage@local    /* get data page */
+       lwz     r5, CLOCK_HRTIMER_RES(r3)
+       mtlr    r12
        li      r3,0
        cmpli   cr0,r4,0
        crclr   cr0*4+so
        beqlr
-       lis     r5,CLOCK_REALTIME_RES@h
-       ori     r5,r5,CLOCK_REALTIME_RES@l
        stw     r3,TSPC32_TV_SEC(r4)
        stw     r5,TSPC32_TV_NSEC(r4)
        blr
index 1f24e41..1c9a047 100644 (file)
@@ -186,12 +186,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
        cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
+       mflr    r12
+  .cfi_register lr,r12
+       bl      V_LOCAL_FUNC(__get_datapage)
+       lwz     r5, CLOCK_HRTIMER_RES(r3)
+       mtlr    r12
        li      r3,0
        cmpldi  cr0,r4,0
        crclr   cr0*4+so
        beqlr
-       lis     r5,CLOCK_REALTIME_RES@h
-       ori     r5,r5,CLOCK_REALTIME_RES@l
        std     r3,TSPC64_TV_SEC(r4)
        std     r5,TSPC64_TV_NSEC(r4)
        blr
index 4c67cc7..2bfeaa1 100644 (file)
@@ -71,6 +71,9 @@ kvm-hv-y += \
        book3s_64_mmu_radix.o \
        book3s_hv_nested.o
 
+kvm-hv-$(CONFIG_PPC_UV) += \
+       book3s_hv_uvmem.o
+
 kvm-hv-$(CONFIG_PPC_TRANSACTIONAL_MEM) += \
        book3s_hv_tm.o
 
index 2d415c3..da857c8 100644 (file)
@@ -19,6 +19,8 @@
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/pte-walk.h>
+#include <asm/ultravisor.h>
+#include <asm/kvm_book3s_uvmem.h>
 
 /*
  * Supported radix tree geometry.
@@ -915,6 +917,9 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
        if (!(dsisr & DSISR_PRTABLE_FAULT))
                gpa |= ea & 0xfff;
 
+       if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
+               return kvmppc_send_page_to_uv(kvm, gfn);
+
        /* Get the corresponding memslot */
        memslot = gfn_to_memslot(kvm, gfn);
 
@@ -972,6 +977,11 @@ int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
        unsigned long gpa = gfn << PAGE_SHIFT;
        unsigned int shift;
 
+       if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE) {
+               uv_page_inval(kvm->arch.lpid, gpa, PAGE_SHIFT);
+               return 0;
+       }
+
        ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift);
        if (ptep && pte_present(*ptep))
                kvmppc_unmap_pte(kvm, ptep, gpa, shift, memslot,
@@ -989,6 +999,9 @@ int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
        int ref = 0;
        unsigned long old, *rmapp;
 
+       if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
+               return ref;
+
        ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift);
        if (ptep && pte_present(*ptep) && pte_young(*ptep)) {
                old = kvmppc_radix_update_pte(kvm, ptep, _PAGE_ACCESSED, 0,
@@ -1013,6 +1026,9 @@ int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
        unsigned int shift;
        int ref = 0;
 
+       if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
+               return ref;
+
        ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift);
        if (ptep && pte_present(*ptep) && pte_young(*ptep))
                ref = 1;
@@ -1030,6 +1046,9 @@ static int kvm_radix_test_clear_dirty(struct kvm *kvm,
        int ret = 0;
        unsigned long old, *rmapp;
 
+       if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
+               return ret;
+
        ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift);
        if (ptep && pte_present(*ptep) && pte_dirty(*ptep)) {
                ret = 1;
@@ -1082,6 +1101,12 @@ void kvmppc_radix_flush_memslot(struct kvm *kvm,
        unsigned long gpa;
        unsigned int shift;
 
+       if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START)
+               kvmppc_uvmem_drop_pages(memslot, kvm);
+
+       if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
+               return;
+
        gpa = memslot->base_gfn << PAGE_SHIFT;
        spin_lock(&kvm->mmu_lock);
        for (n = memslot->npages; n; --n) {
index ec5c037..dc53578 100644 (file)
@@ -72,6 +72,9 @@
 #include <asm/xics.h>
 #include <asm/xive.h>
 #include <asm/hw_breakpoint.h>
+#include <asm/kvm_host.h>
+#include <asm/kvm_book3s_uvmem.h>
+#include <asm/ultravisor.h>
 
 #include "book3s.h"
 
@@ -1070,6 +1073,25 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
                                         kvmppc_get_gpr(vcpu, 5),
                                         kvmppc_get_gpr(vcpu, 6));
                break;
+       case H_SVM_PAGE_IN:
+               ret = kvmppc_h_svm_page_in(vcpu->kvm,
+                                          kvmppc_get_gpr(vcpu, 4),
+                                          kvmppc_get_gpr(vcpu, 5),
+                                          kvmppc_get_gpr(vcpu, 6));
+               break;
+       case H_SVM_PAGE_OUT:
+               ret = kvmppc_h_svm_page_out(vcpu->kvm,
+                                           kvmppc_get_gpr(vcpu, 4),
+                                           kvmppc_get_gpr(vcpu, 5),
+                                           kvmppc_get_gpr(vcpu, 6));
+               break;
+       case H_SVM_INIT_START:
+               ret = kvmppc_h_svm_init_start(vcpu->kvm);
+               break;
+       case H_SVM_INIT_DONE:
+               ret = kvmppc_h_svm_init_done(vcpu->kvm);
+               break;
+
        default:
                return RESUME_HOST;
        }
@@ -4494,6 +4516,29 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
        if (change == KVM_MR_FLAGS_ONLY && kvm_is_radix(kvm) &&
            ((new->flags ^ old->flags) & KVM_MEM_LOG_DIRTY_PAGES))
                kvmppc_radix_flush_memslot(kvm, old);
+       /*
+        * If UV hasn't yet called H_SVM_INIT_START, don't register memslots.
+        */
+       if (!kvm->arch.secure_guest)
+               return;
+
+       switch (change) {
+       case KVM_MR_CREATE:
+               if (kvmppc_uvmem_slot_init(kvm, new))
+                       return;
+               uv_register_mem_slot(kvm->arch.lpid,
+                                    new->base_gfn << PAGE_SHIFT,
+                                    new->npages * PAGE_SIZE,
+                                    0, new->id);
+               break;
+       case KVM_MR_DELETE:
+               uv_unregister_mem_slot(kvm->arch.lpid, old->id);
+               kvmppc_uvmem_slot_free(kvm, old);
+               break;
+       default:
+               /* TODO: Handle KVM_MR_MOVE */
+               break;
+       }
 }
 
 /*
@@ -4767,6 +4812,8 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
        char buf[32];
        int ret;
 
+       mutex_init(&kvm->arch.uvmem_lock);
+       INIT_LIST_HEAD(&kvm->arch.uvmem_pfns);
        mutex_init(&kvm->arch.mmu_setup_lock);
 
        /* Allocate the guest's logical partition ID */
@@ -4936,8 +4983,10 @@ static void kvmppc_core_destroy_vm_hv(struct kvm *kvm)
                if (nesting_enabled(kvm))
                        kvmhv_release_all_nested(kvm);
                kvm->arch.process_table = 0;
+               uv_svm_terminate(kvm->arch.lpid);
                kvmhv_set_ptbl_entry(kvm->arch.lpid, 0, 0);
        }
+
        kvmppc_free_lpid(kvm->arch.lpid);
 
        kvmppc_free_pimap(kvm);
@@ -5377,6 +5426,94 @@ static int kvmhv_store_to_eaddr(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
        return rc;
 }
 
+static void unpin_vpa_reset(struct kvm *kvm, struct kvmppc_vpa *vpa)
+{
+       unpin_vpa(kvm, vpa);
+       vpa->gpa = 0;
+       vpa->pinned_addr = NULL;
+       vpa->dirty = false;
+       vpa->update_pending = 0;
+}
+
+/*
+ *  IOCTL handler to turn off secure mode of guest
+ *
+ * - Release all device pages
+ * - Issue ucall to terminate the guest on the UV side
+ * - Unpin the VPA pages.
+ * - Reinit the partition scoped page tables
+ */
+static int kvmhv_svm_off(struct kvm *kvm)
+{
+       struct kvm_vcpu *vcpu;
+       int mmu_was_ready;
+       int srcu_idx;
+       int ret = 0;
+       int i;
+
+       if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
+               return ret;
+
+       mutex_lock(&kvm->arch.mmu_setup_lock);
+       mmu_was_ready = kvm->arch.mmu_ready;
+       if (kvm->arch.mmu_ready) {
+               kvm->arch.mmu_ready = 0;
+               /* order mmu_ready vs. vcpus_running */
+               smp_mb();
+               if (atomic_read(&kvm->arch.vcpus_running)) {
+                       kvm->arch.mmu_ready = 1;
+                       ret = -EBUSY;
+                       goto out;
+               }
+       }
+
+       srcu_idx = srcu_read_lock(&kvm->srcu);
+       for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
+               struct kvm_memory_slot *memslot;
+               struct kvm_memslots *slots = __kvm_memslots(kvm, i);
+
+               if (!slots)
+                       continue;
+
+               kvm_for_each_memslot(memslot, slots) {
+                       kvmppc_uvmem_drop_pages(memslot, kvm);
+                       uv_unregister_mem_slot(kvm->arch.lpid, memslot->id);
+               }
+       }
+       srcu_read_unlock(&kvm->srcu, srcu_idx);
+
+       ret = uv_svm_terminate(kvm->arch.lpid);
+       if (ret != U_SUCCESS) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /*
+        * When secure guest is reset, all the guest pages are sent
+        * to UV via UV_PAGE_IN before the non-boot vcpus get a
+        * chance to run and unpin their VPA pages. Unpinning of all
+        * VPA pages is done here explicitly so that VPA pages
+        * can be migrated to the secure side.
+        *
+        * This is required to for the secure SMP guest to reboot
+        * correctly.
+        */
+       kvm_for_each_vcpu(i, vcpu, kvm) {
+               spin_lock(&vcpu->arch.vpa_update_lock);
+               unpin_vpa_reset(kvm, &vcpu->arch.dtl);
+               unpin_vpa_reset(kvm, &vcpu->arch.slb_shadow);
+               unpin_vpa_reset(kvm, &vcpu->arch.vpa);
+               spin_unlock(&vcpu->arch.vpa_update_lock);
+       }
+
+       kvmppc_setup_partition_table(kvm);
+       kvm->arch.secure_guest = 0;
+       kvm->arch.mmu_ready = mmu_was_ready;
+out:
+       mutex_unlock(&kvm->arch.mmu_setup_lock);
+       return ret;
+}
+
 static struct kvmppc_ops kvm_ops_hv = {
        .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv,
        .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv,
@@ -5420,6 +5557,7 @@ static struct kvmppc_ops kvm_ops_hv = {
        .enable_nested = kvmhv_enable_nested,
        .load_from_eaddr = kvmhv_load_from_eaddr,
        .store_to_eaddr = kvmhv_store_to_eaddr,
+       .svm_off = kvmhv_svm_off,
 };
 
 static int kvm_init_subcore_bitmap(void)
@@ -5528,11 +5666,16 @@ static int kvmppc_book3s_init_hv(void)
                        no_mixing_hpt_and_radix = true;
        }
 
+       r = kvmppc_uvmem_init();
+       if (r < 0)
+               pr_err("KVM-HV: kvmppc_uvmem_init failed %d\n", r);
+
        return r;
 }
 
 static void kvmppc_book3s_exit_hv(void)
 {
+       kvmppc_uvmem_free();
        kvmppc_free_host_rm_ops();
        if (kvmppc_radix_possible())
                kvmppc_radix_exit();
diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
new file mode 100644 (file)
index 0000000..2de264f
--- /dev/null
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Secure pages management: Migration of pages between normal and secure
+ * memory of KVM guests.
+ *
+ * Copyright 2018 Bharata B Rao, IBM Corp. <bharata@linux.ibm.com>
+ */
+
+/*
+ * A pseries guest can be run as secure guest on Ultravisor-enabled
+ * POWER platforms. On such platforms, this driver will be used to manage
+ * the movement of guest pages between the normal memory managed by
+ * hypervisor (HV) and secure memory managed by Ultravisor (UV).
+ *
+ * The page-in or page-out requests from UV will come to HV as hcalls and
+ * HV will call back into UV via ultracalls to satisfy these page requests.
+ *
+ * Private ZONE_DEVICE memory equal to the amount of secure memory
+ * available in the platform for running secure guests is hotplugged.
+ * Whenever a page belonging to the guest becomes secure, a page from this
+ * private device memory is used to represent and track that secure page
+ * on the HV side. Some pages (like virtio buffers, VPA pages etc) are
+ * shared between UV and HV. However such pages aren't represented by
+ * device private memory and mappings to shared memory exist in both
+ * UV and HV page tables.
+ */
+
+/*
+ * Notes on locking
+ *
+ * kvm->arch.uvmem_lock is a per-guest lock that prevents concurrent
+ * page-in and page-out requests for the same GPA. Concurrent accesses
+ * can either come via UV (guest vCPUs requesting for same page)
+ * or when HV and guest simultaneously access the same page.
+ * This mutex serializes the migration of page from HV(normal) to
+ * UV(secure) and vice versa. So the serialization points are around
+ * migrate_vma routines and page-in/out routines.
+ *
+ * Per-guest mutex comes with a cost though. Mainly it serializes the
+ * fault path as page-out can occur when HV faults on accessing secure
+ * guest pages. Currently UV issues page-in requests for all the guest
+ * PFNs one at a time during early boot (UV_ESM uvcall), so this is
+ * not a cause for concern. Also currently the number of page-outs caused
+ * by HV touching secure pages is very very low. If an when UV supports
+ * overcommitting, then we might see concurrent guest driven page-outs.
+ *
+ * Locking order
+ *
+ * 1. kvm->srcu - Protects KVM memslots
+ * 2. kvm->mm->mmap_sem - find_vma, migrate_vma_pages and helpers, ksm_madvise
+ * 3. kvm->arch.uvmem_lock - protects read/writes to uvmem slots thus acting
+ *                          as sync-points for page-in/out
+ */
+
+/*
+ * Notes on page size
+ *
+ * Currently UV uses 2MB mappings internally, but will issue H_SVM_PAGE_IN
+ * and H_SVM_PAGE_OUT hcalls in PAGE_SIZE(64K) granularity. HV tracks
+ * secure GPAs at 64K page size and maintains one device PFN for each
+ * 64K secure GPA. UV_PAGE_IN and UV_PAGE_OUT calls by HV are also issued
+ * for 64K page at a time.
+ *
+ * HV faulting on secure pages: When HV touches any secure page, it
+ * faults and issues a UV_PAGE_OUT request with 64K page size. Currently
+ * UV splits and remaps the 2MB page if necessary and copies out the
+ * required 64K page contents.
+ *
+ * Shared pages: Whenever guest shares a secure page, UV will split and
+ * remap the 2MB page if required and issue H_SVM_PAGE_IN with 64K page size.
+ *
+ * HV invalidating a page: When a regular page belonging to secure
+ * guest gets unmapped, HV informs UV with UV_PAGE_INVAL of 64K
+ * page size. Using 64K page size is correct here because any non-secure
+ * page will essentially be of 64K page size. Splitting by UV during sharing
+ * and page-out ensures this.
+ *
+ * Page fault handling: When HV handles page fault of a page belonging
+ * to secure guest, it sends that to UV with a 64K UV_PAGE_IN request.
+ * Using 64K size is correct here too as UV would have split the 2MB page
+ * into 64k mappings and would have done page-outs earlier.
+ *
+ * In summary, the current secure pages handling code in HV assumes
+ * 64K page size and in fact fails any page-in/page-out requests of
+ * non-64K size upfront. If and when UV starts supporting multiple
+ * page-sizes, we need to break this assumption.
+ */
+
+#include <linux/pagemap.h>
+#include <linux/migrate.h>
+#include <linux/kvm_host.h>
+#include <linux/ksm.h>
+#include <asm/ultravisor.h>
+#include <asm/mman.h>
+#include <asm/kvm_ppc.h>
+
+static struct dev_pagemap kvmppc_uvmem_pgmap;
+static unsigned long *kvmppc_uvmem_bitmap;
+static DEFINE_SPINLOCK(kvmppc_uvmem_bitmap_lock);
+
+#define KVMPPC_UVMEM_PFN       (1UL << 63)
+
+struct kvmppc_uvmem_slot {
+       struct list_head list;
+       unsigned long nr_pfns;
+       unsigned long base_pfn;
+       unsigned long *pfns;
+};
+
+struct kvmppc_uvmem_page_pvt {
+       struct kvm *kvm;
+       unsigned long gpa;
+       bool skip_page_out;
+};
+
+int kvmppc_uvmem_slot_init(struct kvm *kvm, const struct kvm_memory_slot *slot)
+{
+       struct kvmppc_uvmem_slot *p;
+
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+       p->pfns = vzalloc(array_size(slot->npages, sizeof(*p->pfns)));
+       if (!p->pfns) {
+               kfree(p);
+               return -ENOMEM;
+       }
+       p->nr_pfns = slot->npages;
+       p->base_pfn = slot->base_gfn;
+
+       mutex_lock(&kvm->arch.uvmem_lock);
+       list_add(&p->list, &kvm->arch.uvmem_pfns);
+       mutex_unlock(&kvm->arch.uvmem_lock);
+
+       return 0;
+}
+
+/*
+ * All device PFNs are already released by the time we come here.
+ */
+void kvmppc_uvmem_slot_free(struct kvm *kvm, const struct kvm_memory_slot *slot)
+{
+       struct kvmppc_uvmem_slot *p, *next;
+
+       mutex_lock(&kvm->arch.uvmem_lock);
+       list_for_each_entry_safe(p, next, &kvm->arch.uvmem_pfns, list) {
+               if (p->base_pfn == slot->base_gfn) {
+                       vfree(p->pfns);
+                       list_del(&p->list);
+                       kfree(p);
+                       break;
+               }
+       }
+       mutex_unlock(&kvm->arch.uvmem_lock);
+}
+
+static void kvmppc_uvmem_pfn_insert(unsigned long gfn, unsigned long uvmem_pfn,
+                                   struct kvm *kvm)
+{
+       struct kvmppc_uvmem_slot *p;
+
+       list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) {
+               if (gfn >= p->base_pfn && gfn < p->base_pfn + p->nr_pfns) {
+                       unsigned long index = gfn - p->base_pfn;
+
+                       p->pfns[index] = uvmem_pfn | KVMPPC_UVMEM_PFN;
+                       return;
+               }
+       }
+}
+
+static void kvmppc_uvmem_pfn_remove(unsigned long gfn, struct kvm *kvm)
+{
+       struct kvmppc_uvmem_slot *p;
+
+       list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) {
+               if (gfn >= p->base_pfn && gfn < p->base_pfn + p->nr_pfns) {
+                       p->pfns[gfn - p->base_pfn] = 0;
+                       return;
+               }
+       }
+}
+
+static bool kvmppc_gfn_is_uvmem_pfn(unsigned long gfn, struct kvm *kvm,
+                                   unsigned long *uvmem_pfn)
+{
+       struct kvmppc_uvmem_slot *p;
+
+       list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) {
+               if (gfn >= p->base_pfn && gfn < p->base_pfn + p->nr_pfns) {
+                       unsigned long index = gfn - p->base_pfn;
+
+                       if (p->pfns[index] & KVMPPC_UVMEM_PFN) {
+                               if (uvmem_pfn)
+                                       *uvmem_pfn = p->pfns[index] &
+                                                    ~KVMPPC_UVMEM_PFN;
+                               return true;
+                       } else
+                               return false;
+               }
+       }
+       return false;
+}
+
+unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
+{
+       struct kvm_memslots *slots;
+       struct kvm_memory_slot *memslot;
+       int ret = H_SUCCESS;
+       int srcu_idx;
+
+       if (!kvmppc_uvmem_bitmap)
+               return H_UNSUPPORTED;
+
+       /* Only radix guests can be secure guests */
+       if (!kvm_is_radix(kvm))
+               return H_UNSUPPORTED;
+
+       srcu_idx = srcu_read_lock(&kvm->srcu);
+       slots = kvm_memslots(kvm);
+       kvm_for_each_memslot(memslot, slots) {
+               if (kvmppc_uvmem_slot_init(kvm, memslot)) {
+                       ret = H_PARAMETER;
+                       goto out;
+               }
+               ret = uv_register_mem_slot(kvm->arch.lpid,
+                                          memslot->base_gfn << PAGE_SHIFT,
+                                          memslot->npages * PAGE_SIZE,
+                                          0, memslot->id);
+               if (ret < 0) {
+                       kvmppc_uvmem_slot_free(kvm, memslot);
+                       ret = H_PARAMETER;
+                       goto out;
+               }
+       }
+       kvm->arch.secure_guest |= KVMPPC_SECURE_INIT_START;
+out:
+       srcu_read_unlock(&kvm->srcu, srcu_idx);
+       return ret;
+}
+
+unsigned long kvmppc_h_svm_init_done(struct kvm *kvm)
+{
+       if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
+               return H_UNSUPPORTED;
+
+       kvm->arch.secure_guest |= KVMPPC_SECURE_INIT_DONE;
+       pr_info("LPID %d went secure\n", kvm->arch.lpid);
+       return H_SUCCESS;
+}
+
+/*
+ * Drop device pages that we maintain for the secure guest
+ *
+ * We first mark the pages to be skipped from UV_PAGE_OUT when there
+ * is HV side fault on these pages. Next we *get* these pages, forcing
+ * fault on them, do fault time migration to replace the device PTEs in
+ * QEMU page table with normal PTEs from newly allocated pages.
+ */
+void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
+                            struct kvm *kvm)
+{
+       int i;
+       struct kvmppc_uvmem_page_pvt *pvt;
+       unsigned long pfn, uvmem_pfn;
+       unsigned long gfn = free->base_gfn;
+
+       for (i = free->npages; i; --i, ++gfn) {
+               struct page *uvmem_page;
+
+               mutex_lock(&kvm->arch.uvmem_lock);
+               if (!kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) {
+                       mutex_unlock(&kvm->arch.uvmem_lock);
+                       continue;
+               }
+
+               uvmem_page = pfn_to_page(uvmem_pfn);
+               pvt = uvmem_page->zone_device_data;
+               pvt->skip_page_out = true;
+               mutex_unlock(&kvm->arch.uvmem_lock);
+
+               pfn = gfn_to_pfn(kvm, gfn);
+               if (is_error_noslot_pfn(pfn))
+                       continue;
+               kvm_release_pfn_clean(pfn);
+       }
+}
+
+/*
+ * Get a free device PFN from the pool
+ *
+ * Called when a normal page is moved to secure memory (UV_PAGE_IN). Device
+ * PFN will be used to keep track of the secure page on HV side.
+ *
+ * Called with kvm->arch.uvmem_lock held
+ */
+static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm)
+{
+       struct page *dpage = NULL;
+       unsigned long bit, uvmem_pfn;
+       struct kvmppc_uvmem_page_pvt *pvt;
+       unsigned long pfn_last, pfn_first;
+
+       pfn_first = kvmppc_uvmem_pgmap.res.start >> PAGE_SHIFT;
+       pfn_last = pfn_first +
+                  (resource_size(&kvmppc_uvmem_pgmap.res) >> PAGE_SHIFT);
+
+       spin_lock(&kvmppc_uvmem_bitmap_lock);
+       bit = find_first_zero_bit(kvmppc_uvmem_bitmap,
+                                 pfn_last - pfn_first);
+       if (bit >= (pfn_last - pfn_first))
+               goto out;
+       bitmap_set(kvmppc_uvmem_bitmap, bit, 1);
+       spin_unlock(&kvmppc_uvmem_bitmap_lock);
+
+       pvt = kzalloc(sizeof(*pvt), GFP_KERNEL);
+       if (!pvt)
+               goto out_clear;
+
+       uvmem_pfn = bit + pfn_first;
+       kvmppc_uvmem_pfn_insert(gpa >> PAGE_SHIFT, uvmem_pfn, kvm);
+
+       pvt->gpa = gpa;
+       pvt->kvm = kvm;
+
+       dpage = pfn_to_page(uvmem_pfn);
+       dpage->zone_device_data = pvt;
+       get_page(dpage);
+       lock_page(dpage);
+       return dpage;
+out_clear:
+       spin_lock(&kvmppc_uvmem_bitmap_lock);
+       bitmap_clear(kvmppc_uvmem_bitmap, bit, 1);
+out:
+       spin_unlock(&kvmppc_uvmem_bitmap_lock);
+       return NULL;
+}
+
+/*
+ * Alloc a PFN from private device memory pool and copy page from normal
+ * memory to secure memory using UV_PAGE_IN uvcall.
+ */
+static int
+kvmppc_svm_page_in(struct vm_area_struct *vma, unsigned long start,
+                  unsigned long end, unsigned long gpa, struct kvm *kvm,
+                  unsigned long page_shift, bool *downgrade)
+{
+       unsigned long src_pfn, dst_pfn = 0;
+       struct migrate_vma mig;
+       struct page *spage;
+       unsigned long pfn;
+       struct page *dpage;
+       int ret = 0;
+
+       memset(&mig, 0, sizeof(mig));
+       mig.vma = vma;
+       mig.start = start;
+       mig.end = end;
+       mig.src = &src_pfn;
+       mig.dst = &dst_pfn;
+
+       /*
+        * We come here with mmap_sem write lock held just for
+        * ksm_madvise(), otherwise we only need read mmap_sem.
+        * Hence downgrade to read lock once ksm_madvise() is done.
+        */
+       ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,
+                         MADV_UNMERGEABLE, &vma->vm_flags);
+       downgrade_write(&kvm->mm->mmap_sem);
+       *downgrade = true;
+       if (ret)
+               return ret;
+
+       ret = migrate_vma_setup(&mig);
+       if (ret)
+               return ret;
+
+       if (!(*mig.src & MIGRATE_PFN_MIGRATE)) {
+               ret = -1;
+               goto out_finalize;
+       }
+
+       dpage = kvmppc_uvmem_get_page(gpa, kvm);
+       if (!dpage) {
+               ret = -1;
+               goto out_finalize;
+       }
+
+       pfn = *mig.src >> MIGRATE_PFN_SHIFT;
+       spage = migrate_pfn_to_page(*mig.src);
+       if (spage)
+               uv_page_in(kvm->arch.lpid, pfn << page_shift, gpa, 0,
+                          page_shift);
+
+       *mig.dst = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
+       migrate_vma_pages(&mig);
+out_finalize:
+       migrate_vma_finalize(&mig);
+       return ret;
+}
+
+/*
+ * Shares the page with HV, thus making it a normal page.
+ *
+ * - If the page is already secure, then provision a new page and share
+ * - If the page is a normal page, share the existing page
+ *
+ * In the former case, uses dev_pagemap_ops.migrate_to_ram handler
+ * to unmap the device page from QEMU's page tables.
+ */
+static unsigned long
+kvmppc_share_page(struct kvm *kvm, unsigned long gpa, unsigned long page_shift)
+{
+
+       int ret = H_PARAMETER;
+       struct page *uvmem_page;
+       struct kvmppc_uvmem_page_pvt *pvt;
+       unsigned long pfn;
+       unsigned long gfn = gpa >> page_shift;
+       int srcu_idx;
+       unsigned long uvmem_pfn;
+
+       srcu_idx = srcu_read_lock(&kvm->srcu);
+       mutex_lock(&kvm->arch.uvmem_lock);
+       if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) {
+               uvmem_page = pfn_to_page(uvmem_pfn);
+               pvt = uvmem_page->zone_device_data;
+               pvt->skip_page_out = true;
+       }
+
+retry:
+       mutex_unlock(&kvm->arch.uvmem_lock);
+       pfn = gfn_to_pfn(kvm, gfn);
+       if (is_error_noslot_pfn(pfn))
+               goto out;
+
+       mutex_lock(&kvm->arch.uvmem_lock);
+       if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) {
+               uvmem_page = pfn_to_page(uvmem_pfn);
+               pvt = uvmem_page->zone_device_data;
+               pvt->skip_page_out = true;
+               kvm_release_pfn_clean(pfn);
+               goto retry;
+       }
+
+       if (!uv_page_in(kvm->arch.lpid, pfn << page_shift, gpa, 0, page_shift))
+               ret = H_SUCCESS;
+       kvm_release_pfn_clean(pfn);
+       mutex_unlock(&kvm->arch.uvmem_lock);
+out:
+       srcu_read_unlock(&kvm->srcu, srcu_idx);
+       return ret;
+}
+
+/*
+ * H_SVM_PAGE_IN: Move page from normal memory to secure memory.
+ *
+ * H_PAGE_IN_SHARED flag makes the page shared which means that the same
+ * memory in is visible from both UV and HV.
+ */
+unsigned long
+kvmppc_h_svm_page_in(struct kvm *kvm, unsigned long gpa,
+                    unsigned long flags, unsigned long page_shift)
+{
+       bool downgrade = false;
+       unsigned long start, end;
+       struct vm_area_struct *vma;
+       int srcu_idx;
+       unsigned long gfn = gpa >> page_shift;
+       int ret;
+
+       if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
+               return H_UNSUPPORTED;
+
+       if (page_shift != PAGE_SHIFT)
+               return H_P3;
+
+       if (flags & ~H_PAGE_IN_SHARED)
+               return H_P2;
+
+       if (flags & H_PAGE_IN_SHARED)
+               return kvmppc_share_page(kvm, gpa, page_shift);
+
+       ret = H_PARAMETER;
+       srcu_idx = srcu_read_lock(&kvm->srcu);
+       down_write(&kvm->mm->mmap_sem);
+
+       start = gfn_to_hva(kvm, gfn);
+       if (kvm_is_error_hva(start))
+               goto out;
+
+       mutex_lock(&kvm->arch.uvmem_lock);
+       /* Fail the page-in request of an already paged-in page */
+       if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL))
+               goto out_unlock;
+
+       end = start + (1UL << page_shift);
+       vma = find_vma_intersection(kvm->mm, start, end);
+       if (!vma || vma->vm_start > start || vma->vm_end < end)
+               goto out_unlock;
+
+       if (!kvmppc_svm_page_in(vma, start, end, gpa, kvm, page_shift,
+                               &downgrade))
+               ret = H_SUCCESS;
+out_unlock:
+       mutex_unlock(&kvm->arch.uvmem_lock);
+out:
+       if (downgrade)
+               up_read(&kvm->mm->mmap_sem);
+       else
+               up_write(&kvm->mm->mmap_sem);
+       srcu_read_unlock(&kvm->srcu, srcu_idx);
+       return ret;
+}
+
+/*
+ * Provision a new page on HV side and copy over the contents
+ * from secure memory using UV_PAGE_OUT uvcall.
+ */
+static int
+kvmppc_svm_page_out(struct vm_area_struct *vma, unsigned long start,
+                   unsigned long end, unsigned long page_shift,
+                   struct kvm *kvm, unsigned long gpa)
+{
+       unsigned long src_pfn, dst_pfn = 0;
+       struct migrate_vma mig;
+       struct page *dpage, *spage;
+       struct kvmppc_uvmem_page_pvt *pvt;
+       unsigned long pfn;
+       int ret = U_SUCCESS;
+
+       memset(&mig, 0, sizeof(mig));
+       mig.vma = vma;
+       mig.start = start;
+       mig.end = end;
+       mig.src = &src_pfn;
+       mig.dst = &dst_pfn;
+
+       mutex_lock(&kvm->arch.uvmem_lock);
+       /* The requested page is already paged-out, nothing to do */
+       if (!kvmppc_gfn_is_uvmem_pfn(gpa >> page_shift, kvm, NULL))
+               goto out;
+
+       ret = migrate_vma_setup(&mig);
+       if (ret)
+               return ret;
+
+       spage = migrate_pfn_to_page(*mig.src);
+       if (!spage || !(*mig.src & MIGRATE_PFN_MIGRATE))
+               goto out_finalize;
+
+       if (!is_zone_device_page(spage))
+               goto out_finalize;
+
+       dpage = alloc_page_vma(GFP_HIGHUSER, vma, start);
+       if (!dpage) {
+               ret = -1;
+               goto out_finalize;
+       }
+
+       lock_page(dpage);
+       pvt = spage->zone_device_data;
+       pfn = page_to_pfn(dpage);
+
+       /*
+        * This function is used in two cases:
+        * - When HV touches a secure page, for which we do UV_PAGE_OUT
+        * - When a secure page is converted to shared page, we *get*
+        *   the page to essentially unmap the device page. In this
+        *   case we skip page-out.
+        */
+       if (!pvt->skip_page_out)
+               ret = uv_page_out(kvm->arch.lpid, pfn << page_shift,
+                                 gpa, 0, page_shift);
+
+       if (ret == U_SUCCESS)
+               *mig.dst = migrate_pfn(pfn) | MIGRATE_PFN_LOCKED;
+       else {
+               unlock_page(dpage);
+               __free_page(dpage);
+               goto out_finalize;
+       }
+
+       migrate_vma_pages(&mig);
+out_finalize:
+       migrate_vma_finalize(&mig);
+out:
+       mutex_unlock(&kvm->arch.uvmem_lock);
+       return ret;
+}
+
+/*
+ * Fault handler callback that gets called when HV touches any page that
+ * has been moved to secure memory, we ask UV to give back the page by
+ * issuing UV_PAGE_OUT uvcall.
+ *
+ * This eventually results in dropping of device PFN and the newly
+ * provisioned page/PFN gets populated in QEMU page tables.
+ */
+static vm_fault_t kvmppc_uvmem_migrate_to_ram(struct vm_fault *vmf)
+{
+       struct kvmppc_uvmem_page_pvt *pvt = vmf->page->zone_device_data;
+
+       if (kvmppc_svm_page_out(vmf->vma, vmf->address,
+                               vmf->address + PAGE_SIZE, PAGE_SHIFT,
+                               pvt->kvm, pvt->gpa))
+               return VM_FAULT_SIGBUS;
+       else
+               return 0;
+}
+
+/*
+ * Release the device PFN back to the pool
+ *
+ * Gets called when secure page becomes a normal page during H_SVM_PAGE_OUT.
+ * Gets called with kvm->arch.uvmem_lock held.
+ */
+static void kvmppc_uvmem_page_free(struct page *page)
+{
+       unsigned long pfn = page_to_pfn(page) -
+                       (kvmppc_uvmem_pgmap.res.start >> PAGE_SHIFT);
+       struct kvmppc_uvmem_page_pvt *pvt;
+
+       spin_lock(&kvmppc_uvmem_bitmap_lock);
+       bitmap_clear(kvmppc_uvmem_bitmap, pfn, 1);
+       spin_unlock(&kvmppc_uvmem_bitmap_lock);
+
+       pvt = page->zone_device_data;
+       page->zone_device_data = NULL;
+       kvmppc_uvmem_pfn_remove(pvt->gpa >> PAGE_SHIFT, pvt->kvm);
+       kfree(pvt);
+}
+
+static const struct dev_pagemap_ops kvmppc_uvmem_ops = {
+       .page_free = kvmppc_uvmem_page_free,
+       .migrate_to_ram = kvmppc_uvmem_migrate_to_ram,
+};
+
+/*
+ * H_SVM_PAGE_OUT: Move page from secure memory to normal memory.
+ */
+unsigned long
+kvmppc_h_svm_page_out(struct kvm *kvm, unsigned long gpa,
+                     unsigned long flags, unsigned long page_shift)
+{
+       unsigned long gfn = gpa >> page_shift;
+       unsigned long start, end;
+       struct vm_area_struct *vma;
+       int srcu_idx;
+       int ret;
+
+       if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
+               return H_UNSUPPORTED;
+
+       if (page_shift != PAGE_SHIFT)
+               return H_P3;
+
+       if (flags)
+               return H_P2;
+
+       ret = H_PARAMETER;
+       srcu_idx = srcu_read_lock(&kvm->srcu);
+       down_read(&kvm->mm->mmap_sem);
+       start = gfn_to_hva(kvm, gfn);
+       if (kvm_is_error_hva(start))
+               goto out;
+
+       end = start + (1UL << page_shift);
+       vma = find_vma_intersection(kvm->mm, start, end);
+       if (!vma || vma->vm_start > start || vma->vm_end < end)
+               goto out;
+
+       if (!kvmppc_svm_page_out(vma, start, end, page_shift, kvm, gpa))
+               ret = H_SUCCESS;
+out:
+       up_read(&kvm->mm->mmap_sem);
+       srcu_read_unlock(&kvm->srcu, srcu_idx);
+       return ret;
+}
+
+int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn)
+{
+       unsigned long pfn;
+       int ret = U_SUCCESS;
+
+       pfn = gfn_to_pfn(kvm, gfn);
+       if (is_error_noslot_pfn(pfn))
+               return -EFAULT;
+
+       mutex_lock(&kvm->arch.uvmem_lock);
+       if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL))
+               goto out;
+
+       ret = uv_page_in(kvm->arch.lpid, pfn << PAGE_SHIFT, gfn << PAGE_SHIFT,
+                        0, PAGE_SHIFT);
+out:
+       kvm_release_pfn_clean(pfn);
+       mutex_unlock(&kvm->arch.uvmem_lock);
+       return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT;
+}
+
+static u64 kvmppc_get_secmem_size(void)
+{
+       struct device_node *np;
+       int i, len;
+       const __be32 *prop;
+       u64 size = 0;
+
+       np = of_find_compatible_node(NULL, NULL, "ibm,uv-firmware");
+       if (!np)
+               goto out;
+
+       prop = of_get_property(np, "secure-memory-ranges", &len);
+       if (!prop)
+               goto out_put;
+
+       for (i = 0; i < len / (sizeof(*prop) * 4); i++)
+               size += of_read_number(prop + (i * 4) + 2, 2);
+
+out_put:
+       of_node_put(np);
+out:
+       return size;
+}
+
+int kvmppc_uvmem_init(void)
+{
+       int ret = 0;
+       unsigned long size;
+       struct resource *res;
+       void *addr;
+       unsigned long pfn_last, pfn_first;
+
+       size = kvmppc_get_secmem_size();
+       if (!size) {
+               /*
+                * Don't fail the initialization of kvm-hv module if
+                * the platform doesn't export ibm,uv-firmware node.
+                * Let normal guests run on such PEF-disabled platform.
+                */
+               pr_info("KVMPPC-UVMEM: No support for secure guests\n");
+               goto out;
+       }
+
+       res = request_free_mem_region(&iomem_resource, size, "kvmppc_uvmem");
+       if (IS_ERR(res)) {
+               ret = PTR_ERR(res);
+               goto out;
+       }
+
+       kvmppc_uvmem_pgmap.type = MEMORY_DEVICE_PRIVATE;
+       kvmppc_uvmem_pgmap.res = *res;
+       kvmppc_uvmem_pgmap.ops = &kvmppc_uvmem_ops;
+       addr = memremap_pages(&kvmppc_uvmem_pgmap, NUMA_NO_NODE);
+       if (IS_ERR(addr)) {
+               ret = PTR_ERR(addr);
+               goto out_free_region;
+       }
+
+       pfn_first = res->start >> PAGE_SHIFT;
+       pfn_last = pfn_first + (resource_size(res) >> PAGE_SHIFT);
+       kvmppc_uvmem_bitmap = kcalloc(BITS_TO_LONGS(pfn_last - pfn_first),
+                                     sizeof(unsigned long), GFP_KERNEL);
+       if (!kvmppc_uvmem_bitmap) {
+               ret = -ENOMEM;
+               goto out_unmap;
+       }
+
+       pr_info("KVMPPC-UVMEM: Secure Memory size 0x%lx\n", size);
+       return ret;
+out_unmap:
+       memunmap_pages(&kvmppc_uvmem_pgmap);
+out_free_region:
+       release_mem_region(res->start, size);
+out:
+       return ret;
+}
+
+void kvmppc_uvmem_free(void)
+{
+       memunmap_pages(&kvmppc_uvmem_pgmap);
+       release_mem_region(kvmppc_uvmem_pgmap.res.start,
+                          resource_size(&kvmppc_uvmem_pgmap.res));
+       kfree(kvmppc_uvmem_bitmap);
+}
index 9e085e9..416fb3d 100644 (file)
@@ -31,6 +31,8 @@
 #include <asm/hvcall.h>
 #include <asm/plpar_wrappers.h>
 #endif
+#include <asm/ultravisor.h>
+#include <asm/kvm_host.h>
 
 #include "timing.h"
 #include "irq.h"
@@ -2413,6 +2415,16 @@ long kvm_arch_vm_ioctl(struct file *filp,
                        r = -EFAULT;
                break;
        }
+       case KVM_PPC_SVM_OFF: {
+               struct kvm *kvm = filp->private_data;
+
+               r = 0;
+               if (!kvm->arch.kvm_ops->svm_off)
+                       goto out;
+
+               r = kvm->arch.kvm_ops->svm_off(kvm);
+               break;
+       }
        default: {
                struct kvm *kvm = filp->private_data;
                r = kvm->arch.kvm_ops->arch_vm_ioctl(filp, ioctl, arg);
index 377712e..0666a8d 100644 (file)
@@ -17,14 +17,14 @@ void arch_wb_cache_pmem(void *addr, size_t size)
        unsigned long start = (unsigned long) addr;
        flush_dcache_range(start, start + size);
 }
-EXPORT_SYMBOL(arch_wb_cache_pmem);
+EXPORT_SYMBOL_GPL(arch_wb_cache_pmem);
 
 void arch_invalidate_pmem(void *addr, size_t size)
 {
        unsigned long start = (unsigned long) addr;
        flush_dcache_range(start, start + size);
 }
-EXPORT_SYMBOL(arch_invalidate_pmem);
+EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
 
 /*
  * CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE symbols
index ad299e7..9488b63 100644 (file)
@@ -121,7 +121,7 @@ static void flush_dcache_range_chunked(unsigned long start, unsigned long stop,
        unsigned long i;
 
        for (i = start; i < stop; i += chunk) {
-               flush_dcache_range(i, min(stop, start + chunk));
+               flush_dcache_range(i, min(stop, i + chunk));
                cond_resched();
        }
 }
index 6e5a2a4..4ec2a9f 100644 (file)
@@ -97,12 +97,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
 #ifdef CONFIG_SMP
 #ifdef CONFIG_PPC64
 #define PPC_BPF_LOAD_CPU(r)            \
-       do { BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, paca_index) != 2);   \
+       do { BUILD_BUG_ON(sizeof_field(struct paca_struct, paca_index) != 2);   \
                PPC_LHZ_OFFS(r, 13, offsetof(struct paca_struct, paca_index));  \
        } while (0)
 #else
 #define PPC_BPF_LOAD_CPU(r)     \
-       do { BUILD_BUG_ON(FIELD_SIZEOF(struct task_struct, cpu) != 4);          \
+       do { BUILD_BUG_ON(sizeof_field(struct task_struct, cpu) != 4);          \
                PPC_LHZ_OFFS(r, 2, offsetof(struct task_struct, cpu));          \
        } while(0)
 #endif
index d57b46e..0acc9d5 100644 (file)
@@ -321,7 +321,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                        ctx->seen |= SEEN_XREG | SEEN_MEM | (1<<(K & 0xf));
                        break;
                case BPF_LD | BPF_W | BPF_LEN: /*       A = skb->len; */
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+                       BUILD_BUG_ON(sizeof_field(struct sk_buff, len) != 4);
                        PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len));
                        break;
                case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data + K)); */
@@ -333,16 +333,16 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 
                        /*** Ancillary info loads ***/
                case BPF_ANC | SKF_AD_PROTOCOL: /* A = ntohs(skb->protocol); */
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+                       BUILD_BUG_ON(sizeof_field(struct sk_buff,
                                                  protocol) != 2);
                        PPC_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff,
                                                            protocol));
                        break;
                case BPF_ANC | SKF_AD_IFINDEX:
                case BPF_ANC | SKF_AD_HATYPE:
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
+                       BUILD_BUG_ON(sizeof_field(struct net_device,
                                                ifindex) != 4);
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
+                       BUILD_BUG_ON(sizeof_field(struct net_device,
                                                type) != 2);
                        PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
                                                                dev));
@@ -365,17 +365,17 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 
                        break;
                case BPF_ANC | SKF_AD_MARK:
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+                       BUILD_BUG_ON(sizeof_field(struct sk_buff, mark) != 4);
                        PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
                                                          mark));
                        break;
                case BPF_ANC | SKF_AD_RXHASH:
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
+                       BUILD_BUG_ON(sizeof_field(struct sk_buff, hash) != 4);
                        PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
                                                          hash));
                        break;
                case BPF_ANC | SKF_AD_VLAN_TAG:
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
+                       BUILD_BUG_ON(sizeof_field(struct sk_buff, vlan_tci) != 2);
 
                        PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
                                                          vlan_tci));
@@ -388,7 +388,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                                PPC_ANDI(r_A, r_A, 1);
                        break;
                case BPF_ANC | SKF_AD_QUEUE:
-                       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+                       BUILD_BUG_ON(sizeof_field(struct sk_buff,
                                                  queue_mapping) != 2);
                        PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
                                                          queue_mapping));
index e04b206..000b350 100644 (file)
@@ -59,10 +59,6 @@ static void export_imc_mode_and_cmd(struct device_node *node,
 
        imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root);
 
-       /*
-        * Return here, either because 'imc' directory already exists,
-        * Or failed to create a new one.
-        */
        if (!imc_debugfs_parent)
                return;
 
@@ -135,7 +131,6 @@ static int imc_get_mem_addr_nest(struct device_node *node,
        }
 
        pmu_ptr->imc_counter_mmaped = true;
-       export_imc_mode_and_cmd(node, pmu_ptr);
        kfree(base_addr_arr);
        kfree(chipid_arr);
        return 0;
@@ -151,7 +146,7 @@ error:
  *                 and domain as the inputs.
  * Allocates memory for the struct imc_pmu, sets up its domain, size and offsets
  */
-static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
+static struct imc_pmu *imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
 {
        int ret = 0;
        struct imc_pmu *pmu_ptr;
@@ -159,27 +154,23 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
 
        /* Return for unknown domain */
        if (domain < 0)
-               return -EINVAL;
+               return NULL;
 
        /* memory for pmu */
        pmu_ptr = kzalloc(sizeof(*pmu_ptr), GFP_KERNEL);
        if (!pmu_ptr)
-               return -ENOMEM;
+               return NULL;
 
        /* Set the domain */
        pmu_ptr->domain = domain;
 
        ret = of_property_read_u32(parent, "size", &pmu_ptr->counter_mem_size);
-       if (ret) {
-               ret = -EINVAL;
+       if (ret)
                goto free_pmu;
-       }
 
        if (!of_property_read_u32(parent, "offset", &offset)) {
-               if (imc_get_mem_addr_nest(parent, pmu_ptr, offset)) {
-                       ret = -EINVAL;
+               if (imc_get_mem_addr_nest(parent, pmu_ptr, offset))
                        goto free_pmu;
-               }
        }
 
        /* Function to register IMC pmu */
@@ -190,14 +181,14 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
                if (pmu_ptr->domain == IMC_DOMAIN_NEST)
                        kfree(pmu_ptr->mem_info);
                kfree(pmu_ptr);
-               return ret;
+               return NULL;
        }
 
-       return 0;
+       return pmu_ptr;
 
 free_pmu:
        kfree(pmu_ptr);
-       return ret;
+       return NULL;
 }
 
 static void disable_nest_pmu_counters(void)
@@ -254,6 +245,7 @@ int get_max_nest_dev(void)
 static int opal_imc_counters_probe(struct platform_device *pdev)
 {
        struct device_node *imc_dev = pdev->dev.of_node;
+       struct imc_pmu *pmu;
        int pmu_count = 0, domain;
        bool core_imc_reg = false, thread_imc_reg = false;
        u32 type;
@@ -269,6 +261,7 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
        }
 
        for_each_compatible_node(imc_dev, NULL, IMC_DTB_UNIT_COMPAT) {
+               pmu = NULL;
                if (of_property_read_u32(imc_dev, "type", &type)) {
                        pr_warn("IMC Device without type property\n");
                        continue;
@@ -285,7 +278,14 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
                        domain = IMC_DOMAIN_THREAD;
                        break;
                case IMC_TYPE_TRACE:
-                       domain = IMC_DOMAIN_TRACE;
+                       /*
+                        * FIXME. Using trace_imc events to monitor application
+                        * or KVM thread performance can cause a checkstop
+                        * (system crash).
+                        * Disable it for now.
+                        */
+                       pr_info_once("IMC: disabling trace_imc PMU\n");
+                       domain = -1;
                        break;
                default:
                        pr_warn("IMC Unknown Device type \n");
@@ -293,9 +293,13 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
                        break;
                }
 
-               if (!imc_pmu_create(imc_dev, pmu_count, domain)) {
-                       if (domain == IMC_DOMAIN_NEST)
+               pmu = imc_pmu_create(imc_dev, pmu_count, domain);
+               if (pmu != NULL) {
+                       if (domain == IMC_DOMAIN_NEST) {
+                               if (!imc_debugfs_parent)
+                                       export_imc_mode_and_cmd(imc_dev, pmu);
                                pmu_count++;
+                       }
                        if (domain == IMC_DOMAIN_CORE)
                                core_imc_reg = true;
                        if (domain == IMC_DOMAIN_THREAD)
@@ -303,10 +307,6 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
                }
        }
 
-       /* If none of the nest units are registered, remove debugfs interface */
-       if (pmu_count == 0)
-               debugfs_remove_recursive(imc_debugfs_parent);
-
        /* If core imc is not registered, unregister thread-imc */
        if (!core_imc_reg && thread_imc_reg)
                unregister_thread_imc();
index 33c1074..55dc61c 100644 (file)
@@ -392,20 +392,28 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
        data->esb_shift = esb_shift;
        data->trig_page = trig_page;
 
+       data->hw_irq = hw_irq;
+
        /*
         * No chip-id for the sPAPR backend. This has an impact how we
         * pick a target. See xive_pick_irq_target().
         */
        data->src_chip = XIVE_INVALID_CHIP_ID;
 
+       /*
+        * When the H_INT_ESB flag is set, the H_INT_ESB hcall should
+        * be used for interrupt management. Skip the remapping of the
+        * ESB pages which are not available.
+        */
+       if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB)
+               return 0;
+
        data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift);
        if (!data->eoi_mmio) {
                pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq);
                return -ENOMEM;
        }
 
-       data->hw_irq = hw_irq;
-
        /* Full function page supports trigger */
        if (flags & XIVE_SRC_TRIGGER) {
                data->trig_mmio = data->eoi_mmio;
index 536c0ef..d325b67 100644 (file)
@@ -1,13 +1,13 @@
 menu "SoC selection"
 
 config SOC_SIFIVE
-       bool "SiFive SoCs"
-       select SERIAL_SIFIVE
-       select SERIAL_SIFIVE_CONSOLE
-       select CLK_SIFIVE
-       select CLK_SIFIVE_FU540_PRCI
-       select SIFIVE_PLIC
-       help
-         This enables support for SiFive SoC platform hardware.
+       bool "SiFive SoCs"
+       select SERIAL_SIFIVE if TTY
+       select SERIAL_SIFIVE_CONSOLE if TTY
+       select CLK_SIFIVE
+       select CLK_SIFIVE_FU540_PRCI
+       select SIFIVE_PLIC
+       help
+         This enables support for SiFive SoC platform hardware.
 
 endmenu
index a474f98..36db814 100644 (file)
@@ -24,7 +24,7 @@ $(obj)/Image: vmlinux FORCE
 $(obj)/Image.gz: $(obj)/Image FORCE
        $(call if_changed,gzip)
 
-loader.o: $(src)/loader.S $(obj)/Image
+$(obj)/loader.o: $(src)/loader.S $(obj)/Image
 
 $(obj)/loader: $(obj)/loader.o $(obj)/Image $(obj)/loader.lds FORCE
        $(Q)$(LD) -T $(obj)/loader.lds -o $@ $(obj)/loader.o
index 420a0db..e2ff95c 100644 (file)
@@ -100,4 +100,28 @@ CONFIG_9P_FS=y
 CONFIG_CRYPTO_USER_API_HASH=y
 CONFIG_CRYPTO_DEV_VIRTIO=y
 CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_VM_PGFLAGS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_PER_CPU_MAPS=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_PLIST=y
+CONFIG_DEBUG_SG=y
 # CONFIG_RCU_TRACE is not set
+CONFIG_RCU_EQS_DEBUG=y
+CONFIG_DEBUG_BLOCK_EXT_DEVT=y
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_MEMTEST=y
index 87ee6e6..eb51940 100644 (file)
@@ -97,4 +97,28 @@ CONFIG_9P_FS=y
 CONFIG_CRYPTO_USER_API_HASH=y
 CONFIG_CRYPTO_DEV_VIRTIO=y
 CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_VM_PGFLAGS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_PER_CPU_MAPS=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_PLIST=y
+CONFIG_DEBUG_SG=y
 # CONFIG_RCU_TRACE is not set
+CONFIG_RCU_EQS_DEBUG=y
+CONFIG_DEBUG_BLOCK_EXT_DEVT=y
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_MEMTEST=y
index b2fe9d1..69f6678 100644 (file)
@@ -46,6 +46,37 @@ static void setup_zero_page(void)
        memset((void *)empty_zero_page, 0, PAGE_SIZE);
 }
 
+#ifdef CONFIG_DEBUG_VM
+static inline void print_mlk(char *name, unsigned long b, unsigned long t)
+{
+       pr_notice("%12s : 0x%08lx - 0x%08lx   (%4ld kB)\n", name, b, t,
+                 (((t) - (b)) >> 10));
+}
+
+static inline void print_mlm(char *name, unsigned long b, unsigned long t)
+{
+       pr_notice("%12s : 0x%08lx - 0x%08lx   (%4ld MB)\n", name, b, t,
+                 (((t) - (b)) >> 20));
+}
+
+static void print_vm_layout(void)
+{
+       pr_notice("Virtual kernel memory layout:\n");
+       print_mlk("fixmap", (unsigned long)FIXADDR_START,
+                 (unsigned long)FIXADDR_TOP);
+       print_mlm("pci io", (unsigned long)PCI_IO_START,
+                 (unsigned long)PCI_IO_END);
+       print_mlm("vmemmap", (unsigned long)VMEMMAP_START,
+                 (unsigned long)VMEMMAP_END);
+       print_mlm("vmalloc", (unsigned long)VMALLOC_START,
+                 (unsigned long)VMALLOC_END);
+       print_mlm("lowmem", (unsigned long)PAGE_OFFSET,
+                 (unsigned long)high_memory);
+}
+#else
+static void print_vm_layout(void) { }
+#endif /* CONFIG_DEBUG_VM */
+
 void __init mem_init(void)
 {
 #ifdef CONFIG_FLATMEM
@@ -56,6 +87,7 @@ void __init mem_init(void)
        memblock_free_all();
 
        mem_init_print_info(NULL);
+       print_vm_layout();
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
index d4051e8..bc88841 100644 (file)
@@ -124,6 +124,7 @@ config S390
        select HAVE_ARCH_JUMP_LABEL
        select HAVE_ARCH_JUMP_LABEL_RELATIVE
        select HAVE_ARCH_KASAN
+       select HAVE_ARCH_KASAN_VMALLOC
        select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_SOFT_DIRTY
index eb7eed4..431e208 100644 (file)
@@ -241,7 +241,9 @@ static inline void arch___clear_bit_unlock(unsigned long nr,
        arch___clear_bit(nr, ptr);
 }
 
-#include <asm-generic/bitops-instrumented.h>
+#include <asm-generic/bitops/instrumented-atomic.h>
+#include <asm-generic/bitops/instrumented-non-atomic.h>
+#include <asm-generic/bitops/instrumented-lock.h>
 
 /*
  * Functions which use MSB0 bit numbering.
index 6dc6c4f..69289e9 100644 (file)
@@ -27,7 +27,6 @@
 #define MACHINE_FLAG_DIAG9C    BIT(3)
 #define MACHINE_FLAG_ESOP      BIT(4)
 #define MACHINE_FLAG_IDTE      BIT(5)
-#define MACHINE_FLAG_DIAG44    BIT(6)
 #define MACHINE_FLAG_EDAT1     BIT(7)
 #define MACHINE_FLAG_EDAT2     BIT(8)
 #define MACHINE_FLAG_TOPOLOGY  BIT(10)
@@ -94,7 +93,6 @@ extern unsigned long __swsusp_reset_dma;
 #define MACHINE_HAS_DIAG9C     (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C)
 #define MACHINE_HAS_ESOP       (S390_lowcore.machine_flags & MACHINE_FLAG_ESOP)
 #define MACHINE_HAS_IDTE       (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE)
-#define MACHINE_HAS_DIAG44     (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG44)
 #define MACHINE_HAS_EDAT1      (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1)
 #define MACHINE_HAS_EDAT2      (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2)
 #define MACHINE_HAS_TOPOLOGY   (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
index ef3c00b..4093a28 100644 (file)
@@ -86,7 +86,7 @@ static inline int share(unsigned long addr, u16 cmd)
        };
 
        if (!is_prot_virt_guest())
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
        /*
         * Sharing is page wise, if we encounter addresses that are
         * not page aligned, we assume something went wrong. If
index 5b1c4f4..1030cd1 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef __S390_IPCBUF_H__
 #define __S390_IPCBUF_H__
 
+#include <linux/posix_types.h>
+
 /*
  * The user_ipc_perm structure for S/390 architecture.
  * Note extra padding because this structure is passed back and forth
index db32a55..cd241ee 100644 (file)
@@ -204,21 +204,6 @@ static __init void detect_diag9c(void)
                S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C;
 }
 
-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"
-               "1:\n"
-               EX_TABLE(0b,1b)
-               : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc");
-       if (!rc)
-               S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG44;
-}
-
 static __init void detect_machine_facilities(void)
 {
        if (test_facility(8)) {
@@ -331,7 +316,6 @@ void __init startup_init(void)
        setup_arch_string();
        setup_boot_command_line();
        detect_diag9c();
-       detect_diag44();
        detect_machine_facilities();
        save_vector_registers();
        setup_topology();
index c07fdcd..77d93c5 100644 (file)
@@ -1303,18 +1303,28 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all)
                 */
                if (flush_all && done)
                        break;
-
-               /* If an event overflow happened, discard samples by
-                * processing any remaining sample-data-blocks.
-                */
-               if (event_overflow)
-                       flush_all = 1;
        }
 
        /* Account sample overflows in the event hardware structure */
        if (sampl_overflow)
                OVERFLOW_REG(hwc) = DIV_ROUND_UP(OVERFLOW_REG(hwc) +
                                                 sampl_overflow, 1 + num_sdb);
+
+       /* Perf_event_overflow() and perf_event_account_interrupt() limit
+        * the interrupt rate to an upper limit. Roughly 1000 samples per
+        * task tick.
+        * Hitting this limit results in a large number
+        * of throttled REF_REPORT_THROTTLE entries and the samples
+        * are dropped.
+        * Slightly increase the interval to avoid hitting this limit.
+        */
+       if (event_overflow) {
+               SAMPL_RATE(hwc) += DIV_ROUND_UP(SAMPL_RATE(hwc), 10);
+               debug_sprintf_event(sfdbg, 1, "%s: rate adjustment %ld\n",
+                                   __func__,
+                                   DIV_ROUND_UP(SAMPL_RATE(hwc), 10));
+       }
+
        if (sampl_overflow || event_overflow)
                debug_sprintf_event(sfdbg, 4, "%s: "
                                    "overflows: sample %llu event %llu"
index 2794cad..a08bd25 100644 (file)
@@ -413,14 +413,11 @@ EXPORT_SYMBOL(arch_vcpu_is_preempted);
 
 void smp_yield_cpu(int cpu)
 {
-       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 && !smp_cpu_mtid) {
-               diag_stat_inc_norecursion(DIAG_STAT_X044);
-               asm volatile("diag 0,0,0x44");
-       }
+       if (!MACHINE_HAS_DIAG9C)
+               return;
+       diag_stat_inc_norecursion(DIAG_STAT_X09C);
+       asm volatile("diag %0,0,0x9c"
+                    : : "d" (pcpu_devices[cpu].address));
 }
 
 /*
index ce1e4bb..9b2dab5 100644 (file)
@@ -242,7 +242,6 @@ static inline void arch_spin_lock_classic(arch_spinlock_t *lp)
 
 void arch_spin_lock_wait(arch_spinlock_t *lp)
 {
-       /* Use classic spinlocks + niai if the steal time is >= 10% */
        if (test_cpu_flag(CIF_DEDICATED_CPU))
                arch_spin_lock_queued(lp);
        else
index bda7ac0..32b7a30 100644 (file)
@@ -238,7 +238,7 @@ static int test_unwind_irq(struct unwindme *u)
 {
        preempt_disable();
        if (register_external_irq(EXT_IRQ_CLK_COMP, unwindme_irq_handler)) {
-               pr_info("Couldn't reqister external interrupt handler");
+               pr_info("Couldn't register external interrupt handler");
                return -1;
        }
        u->task = current;
index 460f255..0634561 100644 (file)
@@ -82,7 +82,8 @@ static pte_t * __init kasan_early_pte_alloc(void)
 enum populate_mode {
        POPULATE_ONE2ONE,
        POPULATE_MAP,
-       POPULATE_ZERO_SHADOW
+       POPULATE_ZERO_SHADOW,
+       POPULATE_SHALLOW
 };
 static void __init kasan_early_vmemmap_populate(unsigned long address,
                                                unsigned long end,
@@ -116,6 +117,12 @@ static void __init kasan_early_vmemmap_populate(unsigned long address,
                        pgd_populate(&init_mm, pg_dir, p4_dir);
                }
 
+               if (IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING) &&
+                   mode == POPULATE_SHALLOW) {
+                       address = (address + P4D_SIZE) & P4D_MASK;
+                       continue;
+               }
+
                p4_dir = p4d_offset(pg_dir, address);
                if (p4d_none(*p4_dir)) {
                        if (mode == POPULATE_ZERO_SHADOW &&
@@ -130,6 +137,12 @@ static void __init kasan_early_vmemmap_populate(unsigned long address,
                        p4d_populate(&init_mm, p4_dir, pu_dir);
                }
 
+               if (!IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING) &&
+                   mode == POPULATE_SHALLOW) {
+                       address = (address + PUD_SIZE) & PUD_MASK;
+                       continue;
+               }
+
                pu_dir = pud_offset(p4_dir, address);
                if (pud_none(*pu_dir)) {
                        if (mode == POPULATE_ZERO_SHADOW &&
@@ -195,6 +208,9 @@ static void __init kasan_early_vmemmap_populate(unsigned long address,
                                page = kasan_early_shadow_page;
                                pte_val(*pt_dir) = __pa(page) | pgt_prot_zero;
                                break;
+                       case POPULATE_SHALLOW:
+                               /* should never happen */
+                               break;
                        }
                }
                address += PAGE_SIZE;
@@ -313,22 +329,50 @@ void __init kasan_early_init(void)
        init_mm.pgd = early_pg_dir;
        /*
         * Current memory layout:
-        * +- 0 -------------+   +- shadow start -+
-        * | 1:1 ram mapping |  /| 1/8 ram        |
-        * +- end of ram ----+ / +----------------+
-        * | ... gap ...     |/  |      kasan     |
-        * +- shadow start --+   |      zero      |
-        * | 1/8 addr space  |   |      page      |
-        * +- shadow end    -+   |      mapping   |
-        * | ... gap ...     |\  |    (untracked) |
-        * +- modules vaddr -+ \ +----------------+
-        * | 2Gb             |  \|      unmapped  | allocated per module
-        * +-----------------+   +- shadow end ---+
+        * +- 0 -------------+     +- shadow start -+
+        * | 1:1 ram mapping |    /| 1/8 ram        |
+        * |                 |   / |                |
+        * +- end of ram ----+  /  +----------------+
+        * | ... gap ...     | /   |                |
+        * |                 |/    |    kasan       |
+        * +- shadow start --+     |    zero        |
+        * | 1/8 addr space  |     |    page        |
+        * +- shadow end    -+     |    mapping     |
+        * | ... gap ...     |\    |  (untracked)   |
+        * +- vmalloc area  -+ \   |                |
+        * | vmalloc_size    |  \  |                |
+        * +- modules vaddr -+   \ +----------------+
+        * | 2Gb             |    \|      unmapped  | allocated per module
+        * +-----------------+     +- shadow end ---+
+        *
+        * Current memory layout (KASAN_VMALLOC):
+        * +- 0 -------------+     +- shadow start -+
+        * | 1:1 ram mapping |    /| 1/8 ram        |
+        * |                 |   / |                |
+        * +- end of ram ----+  /  +----------------+
+        * | ... gap ...     | /   |    kasan       |
+        * |                 |/    |    zero        |
+        * +- shadow start --+     |    page        |
+        * | 1/8 addr space  |     |    mapping     |
+        * +- shadow end    -+     |  (untracked)   |
+        * | ... gap ...     |\    |                |
+        * +- vmalloc area  -+ \   +- vmalloc area -+
+        * | vmalloc_size    |  \  |shallow populate|
+        * +- modules vaddr -+   \ +- modules area -+
+        * | 2Gb             |    \|shallow populate|
+        * +-----------------+     +- shadow end ---+
         */
        /* populate kasan shadow (for identity mapping and zero page mapping) */
        kasan_early_vmemmap_populate(__sha(0), __sha(memsize), POPULATE_MAP);
        if (IS_ENABLED(CONFIG_MODULES))
                untracked_mem_end = vmax - MODULES_LEN;
+       if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
+               untracked_mem_end = vmax - vmalloc_size - MODULES_LEN;
+               /* shallowly populate kasan shadow for vmalloc and modules */
+               kasan_early_vmemmap_populate(__sha(untracked_mem_end),
+                                            __sha(vmax), POPULATE_SHALLOW);
+       }
+       /* populate kasan shadow for untracked memory */
        kasan_early_vmemmap_populate(__sha(max_physmem_end),
                                     __sha(untracked_mem_end),
                                     POPULATE_ZERO_SHADOW);
index f6d1484..f3dc3f2 100644 (file)
@@ -325,9 +325,9 @@ int __init sh_early_platform_driver_probe(char *class_str,
 }
 
 /**
- * sh_early_platform_cleanup - clean up early platform code
+ * early_platform_cleanup - clean up early platform code
  */
-static int __init sh_early_platform_cleanup(void)
+void __init early_platform_cleanup(void)
 {
        struct platform_device *pd, *pd2;
 
@@ -337,11 +337,4 @@ static int __init sh_early_platform_cleanup(void)
                list_del(&pd->dev.devres_head);
                memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
        }
-
-       return 0;
 }
-/*
- * This must happen once after all early devices are probed but before probing
- * real platform devices.
- */
-subsys_initcall(sh_early_platform_cleanup);
index dbd2cde..b0f9c8f 100644 (file)
@@ -67,7 +67,7 @@ static struct cpuidle_driver cpuidle_driver = {
                        .enter = cpuidle_sleep_enter,
                        .name = "C2",
                        .desc = "SuperH Sleep Mode [SF]",
-                       .disabled = true,
+                       .flags = CPUIDLE_FLAG_UNUSABLE,
                },
                {
                        .exit_latency = 2300,
@@ -76,7 +76,7 @@ static struct cpuidle_driver cpuidle_driver = {
                        .enter = cpuidle_sleep_enter,
                        .name = "C3",
                        .desc = "SuperH Mobile Standby Mode [SF]",
-                       .disabled = true,
+                       .flags = CPUIDLE_FLAG_UNUSABLE,
                },
        },
        .safe_state_index = 0,
@@ -86,10 +86,10 @@ static struct cpuidle_driver cpuidle_driver = {
 int __init sh_mobile_setup_cpuidle(void)
 {
        if (sh_mobile_sleep_supported & SUSP_SH_SF)
-               cpuidle_driver.states[1].disabled = false;
+               cpuidle_driver.states[1].flags = CPUIDLE_FLAG_NONE;
 
        if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)
-               cpuidle_driver.states[2].disabled = false;
+               cpuidle_driver.states[2].flags = CPUIDLE_FLAG_NONE;
 
        return cpuidle_register(&cpuidle_driver, NULL);
 }
index 6d61f8c..0d5f3c9 100644 (file)
@@ -266,6 +266,7 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
                ptr = &remcomInBuffer[1];
                if (kgdb_hex2long(&ptr, &addr))
                        linux_regs->pc = addr;
+               /* fallthrough */
        case 'D':
        case 'k':
                atomic_set(&kgdb_cpu_doing_single_step, -1);
index 10538a4..eae0c92 100644 (file)
@@ -26,14 +26,14 @@ static inline void free_pgd_fast(pgd_t *pgd)
 #define pgd_free(mm, pgd)      free_pgd_fast(pgd)
 #define pgd_alloc(mm)  get_pgd_fast()
 
-static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+static inline void pud_set(pud_t * pudp, pmd_t * pmdp)
 {
        unsigned long pa = __nocache_pa(pmdp);
 
-       set_pte((pte_t *)pgdp, __pte((SRMMU_ET_PTD | (pa >> 4))));
+       set_pte((pte_t *)pudp, __pte((SRMMU_ET_PTD | (pa >> 4))));
 }
 
-#define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, PMD)
+#define pud_populate(MM, PGD, PMD)      pud_set(PGD, PMD)
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm,
                                   unsigned long address)
index 31da448..6d6f44c 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/const.h>
 
 #ifndef __ASSEMBLY__
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 #include <linux/spinlock.h>
 #include <linux/mm_types.h>
@@ -132,12 +132,12 @@ static inline struct page *pmd_page(pmd_t pmd)
        return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4));
 }
 
-static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+static inline unsigned long pud_page_vaddr(pud_t pud)
 {
-       if (srmmu_device_memory(pgd_val(pgd))) {
+       if (srmmu_device_memory(pud_val(pud))) {
                return ~0;
        } else {
-               unsigned long v = pgd_val(pgd) & SRMMU_PTD_PMASK;
+               unsigned long v = pud_val(pud) & SRMMU_PTD_PMASK;
                return (unsigned long)__nocache_va(v << 4);
        }
 }
@@ -184,24 +184,24 @@ static inline void pmd_clear(pmd_t *pmdp)
                set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
 }
 
-static inline int pgd_none(pgd_t pgd)          
+static inline int pud_none(pud_t pud)
 {
-       return !(pgd_val(pgd) & 0xFFFFFFF);
+       return !(pud_val(pud) & 0xFFFFFFF);
 }
 
-static inline int pgd_bad(pgd_t pgd)
+static inline int pud_bad(pud_t pud)
 {
-       return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
+       return (pud_val(pud) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
 }
 
-static inline int pgd_present(pgd_t pgd)
+static inline int pud_present(pud_t pud)
 {
-       return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
+       return ((pud_val(pud) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
 }
 
-static inline void pgd_clear(pgd_t *pgdp)
+static inline void pud_clear(pud_t *pudp)
 {
-       set_pte((pte_t *)pgdp, __pte(0));
+       set_pte((pte_t *)pudp, __pte(0));
 }
 
 /*
@@ -319,9 +319,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 /* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t *pmd_offset(pud_t * dir, unsigned long address)
 {
-       return (pmd_t *) pgd_page_vaddr(*dir) +
+       return (pmd_t *) pud_page_vaddr(*dir) +
                ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
 }
 
index 9d0d125..5b933a5 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef __SPARC_IPCBUF_H
 #define __SPARC_IPCBUF_H
 
+#include <linux/posix_types.h>
+
 /*
  * The ipc64_perm structure for sparc/sparc64 architecture.
  * Note extra padding because this structure is passed back and forth
index eeeb919..0954552 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _SPARC_MSGBUF_H
 #define _SPARC_MSGBUF_H
 
+#include <asm/ipcbuf.h>
+
 /*
  * The msqid64_ds structure for sparc64 architecture.
  * Note extra padding because this structure is passed back and forth
index cbcbaa4..10621d0 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _SPARC_SEMBUF_H
 #define _SPARC_SEMBUF_H
 
+#include <asm/ipcbuf.h>
+
 /*
  * The semid64_ds structure for sparc architecture.
  * Note extra padding because this structure is passed back and forth
index 8d69de1..89976c9 100644 (file)
@@ -351,6 +351,8 @@ vmalloc_fault:
                 */
                int offset = pgd_index(address);
                pgd_t *pgd, *pgd_k;
+               p4d_t *p4d, *p4d_k;
+               pud_t *pud, *pud_k;
                pmd_t *pmd, *pmd_k;
 
                pgd = tsk->active_mm->pgd + offset;
@@ -363,8 +365,13 @@ vmalloc_fault:
                        return;
                }
 
-               pmd = pmd_offset(pgd, address);
-               pmd_k = pmd_offset(pgd_k, address);
+               p4d = p4d_offset(pgd, address);
+               pud = pud_offset(p4d, address);
+               pmd = pmd_offset(pud, address);
+
+               p4d_k = p4d_offset(pgd_k, address);
+               pud_k = pud_offset(p4d_k, address);
+               pmd_k = pmd_offset(pud_k, address);
 
                if (pmd_present(*pmd) || !pmd_present(*pmd_k))
                        goto bad_area_nosemaphore;
index 86bc2a5..d4a80ad 100644 (file)
@@ -39,10 +39,14 @@ static pte_t *kmap_pte;
 void __init kmap_init(void)
 {
        unsigned long address;
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *dir;
 
        address = __fix_to_virt(FIX_KMAP_BEGIN);
-       dir = pmd_offset(pgd_offset_k(address), address);
+       p4d = p4d_offset(pgd_offset_k(address), address);
+       pud = pud_offset(p4d, address);
+       dir = pmd_offset(pud, address);
 
         /* cache the first kmap pte */
         kmap_pte = pte_offset_kernel(dir, address);
index f770ee7..33a0fac 100644 (file)
@@ -239,12 +239,16 @@ static void *iounit_alloc(struct device *dev, size_t len,
                page = va;
                {
                        pgd_t *pgdp;
+                       p4d_t *p4dp;
+                       pud_t *pudp;
                        pmd_t *pmdp;
                        pte_t *ptep;
                        long i;
 
                        pgdp = pgd_offset(&init_mm, addr);
-                       pmdp = pmd_offset(pgdp, addr);
+                       p4dp = p4d_offset(pgdp, addr);
+                       pudp = pud_offset(p4dp, addr);
+                       pmdp = pmd_offset(pudp, addr);
                        ptep = pte_offset_map(pmdp, addr);
 
                        set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
index 71ac353..4d3c699 100644 (file)
@@ -343,6 +343,8 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
                page = va;
                {
                        pgd_t *pgdp;
+                       p4d_t *p4dp;
+                       pud_t *pudp;
                        pmd_t *pmdp;
                        pte_t *ptep;
 
@@ -354,7 +356,9 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
                                __flush_page_to_ram(page);
 
                        pgdp = pgd_offset(&init_mm, addr);
-                       pmdp = pmd_offset(pgdp, addr);
+                       p4dp = p4d_offset(pgdp, addr);
+                       pudp = pud_offset(p4dp, addr);
+                       pmdp = pmd_offset(pudp, addr);
                        ptep = pte_offset_map(pmdp, addr);
 
                        set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
index cc3ad64..f56c3c9 100644 (file)
@@ -296,6 +296,8 @@ static void __init srmmu_nocache_init(void)
        void *srmmu_nocache_bitmap;
        unsigned int bitmap_bits;
        pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        unsigned long paddr, vaddr;
@@ -329,6 +331,8 @@ static void __init srmmu_nocache_init(void)
 
        while (vaddr < srmmu_nocache_end) {
                pgd = pgd_offset_k(vaddr);
+               p4d = p4d_offset(__nocache_fix(pgd), vaddr);
+               pud = pud_offset(__nocache_fix(p4d), vaddr);
                pmd = pmd_offset(__nocache_fix(pgd), vaddr);
                pte = pte_offset_kernel(__nocache_fix(pmd), vaddr);
 
@@ -516,13 +520,17 @@ static inline void srmmu_mapioaddr(unsigned long physaddr,
                                   unsigned long virt_addr, int bus_type)
 {
        pgd_t *pgdp;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
        unsigned long tmp;
 
        physaddr &= PAGE_MASK;
        pgdp = pgd_offset_k(virt_addr);
-       pmdp = pmd_offset(pgdp, virt_addr);
+       p4dp = p4d_offset(pgdp, virt_addr);
+       pudp = pud_offset(p4dp, virt_addr);
+       pmdp = pmd_offset(pudp, virt_addr);
        ptep = pte_offset_kernel(pmdp, virt_addr);
        tmp = (physaddr >> 4) | SRMMU_ET_PTE;
 
@@ -551,11 +559,16 @@ void srmmu_mapiorange(unsigned int bus, unsigned long xpa,
 static inline void srmmu_unmapioaddr(unsigned long virt_addr)
 {
        pgd_t *pgdp;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
 
+
        pgdp = pgd_offset_k(virt_addr);
-       pmdp = pmd_offset(pgdp, virt_addr);
+       p4dp = p4d_offset(pgdp, virt_addr);
+       pudp = pud_offset(p4dp, virt_addr);
+       pmdp = pmd_offset(pudp, virt_addr);
        ptep = pte_offset_kernel(pmdp, virt_addr);
 
        /* No need to flush uncacheable page. */
@@ -693,20 +706,24 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
                                                        unsigned long end)
 {
        pgd_t *pgdp;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
 
        while (start < end) {
                pgdp = pgd_offset_k(start);
-               if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+               p4dp = p4d_offset(pgdp, start);
+               pudp = pud_offset(p4dp, start);
+               if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
                        pmdp = __srmmu_get_nocache(
                            SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
                        if (pmdp == NULL)
                                early_pgtable_allocfail("pmd");
                        memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
-                       pgd_set(__nocache_fix(pgdp), pmdp);
+                       pud_set(__nocache_fix(pudp), pmdp);
                }
-               pmdp = pmd_offset(__nocache_fix(pgdp), start);
+               pmdp = pmd_offset(__nocache_fix(pudp), start);
                if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
                        ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
                        if (ptep == NULL)
@@ -724,19 +741,23 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
                                                  unsigned long end)
 {
        pgd_t *pgdp;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
 
        while (start < end) {
                pgdp = pgd_offset_k(start);
-               if (pgd_none(*pgdp)) {
+               p4dp = p4d_offset(pgdp, start);
+               pudp = pud_offset(p4dp, start);
+               if (pud_none(*pudp)) {
                        pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
                        if (pmdp == NULL)
                                early_pgtable_allocfail("pmd");
                        memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE);
-                       pgd_set(pgdp, pmdp);
+                       pud_set((pud_t *)pgdp, pmdp);
                }
-               pmdp = pmd_offset(pgdp, start);
+               pmdp = pmd_offset(pudp, start);
                if (srmmu_pmd_none(*pmdp)) {
                        ptep = __srmmu_get_nocache(PTE_SIZE,
                                                             PTE_SIZE);
@@ -779,6 +800,8 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
        unsigned long probed;
        unsigned long addr;
        pgd_t *pgdp;
+       p4d_t *p4dp;
+       pud_t *pudp;
        pmd_t *pmdp;
        pte_t *ptep;
        int what; /* 0 = normal-pte, 1 = pmd-level pte, 2 = pgd-level pte */
@@ -810,18 +833,20 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
                }
 
                pgdp = pgd_offset_k(start);
+               p4dp = p4d_offset(pgdp, start);
+               pudp = pud_offset(p4dp, start);
                if (what == 2) {
                        *(pgd_t *)__nocache_fix(pgdp) = __pgd(probed);
                        start += SRMMU_PGDIR_SIZE;
                        continue;
                }
-               if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+               if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
                        pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
                                                   SRMMU_PMD_TABLE_SIZE);
                        if (pmdp == NULL)
                                early_pgtable_allocfail("pmd");
                        memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
-                       pgd_set(__nocache_fix(pgdp), pmdp);
+                       pud_set(__nocache_fix(pudp), pmdp);
                }
                pmdp = pmd_offset(__nocache_fix(pgdp), start);
                if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
@@ -906,6 +931,8 @@ void __init srmmu_paging_init(void)
        phandle cpunode;
        char node_str[128];
        pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        unsigned long pages_avail;
@@ -967,7 +994,9 @@ void __init srmmu_paging_init(void)
        srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_END);
 
        pgd = pgd_offset_k(PKMAP_BASE);
-       pmd = pmd_offset(pgd, PKMAP_BASE);
+       p4d = p4d_offset(pgd, PKMAP_BASE);
+       pud = pud_offset(p4d, PKMAP_BASE);
+       pmd = pmd_offset(pud, PKMAP_BASE);
        pte = pte_offset_kernel(pmd, PKMAP_BASE);
        pkmap_page_table = pte;
 
index 84cc8f7..c8eabb9 100644 (file)
@@ -180,19 +180,19 @@ do {                                                                      \
 
 #define emit_loadptr(BASE, STRUCT, FIELD, DEST)                                \
 do {   unsigned int _off = offsetof(STRUCT, FIELD);                    \
-       BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(void *));    \
+       BUILD_BUG_ON(sizeof_field(STRUCT, FIELD) != sizeof(void *));    \
        *prog++ = LDPTRI | RS1(BASE) | S13(_off) | RD(DEST);            \
 } while (0)
 
 #define emit_load32(BASE, STRUCT, FIELD, DEST)                         \
 do {   unsigned int _off = offsetof(STRUCT, FIELD);                    \
-       BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(u32));       \
+       BUILD_BUG_ON(sizeof_field(STRUCT, FIELD) != sizeof(u32));       \
        *prog++ = LD32I | RS1(BASE) | S13(_off) | RD(DEST);             \
 } while (0)
 
 #define emit_load16(BASE, STRUCT, FIELD, DEST)                         \
 do {   unsigned int _off = offsetof(STRUCT, FIELD);                    \
-       BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(u16));       \
+       BUILD_BUG_ON(sizeof_field(STRUCT, FIELD) != sizeof(u16));       \
        *prog++ = LD16I | RS1(BASE) | S13(_off) | RD(DEST);             \
 } while (0)
 
@@ -202,7 +202,7 @@ do {        unsigned int _off = offsetof(STRUCT, FIELD);                    \
 } while (0)
 
 #define emit_load8(BASE, STRUCT, FIELD, DEST)                          \
-do {   BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(u8));        \
+do {   BUILD_BUG_ON(sizeof_field(STRUCT, FIELD) != sizeof(u8));        \
        __emit_load8(BASE, STRUCT, FIELD, DEST);                        \
 } while (0)
 
index 32b3d26..32106d3 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef __UM_PGTABLE_2LEVEL_H
 #define __UM_PGTABLE_2LEVEL_H
 
-#define __ARCH_USE_5LEVEL_HACK
 #include <asm-generic/pgtable-nopmd.h>
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
index 9812269..8a3b689 100644 (file)
@@ -7,7 +7,6 @@
 #ifndef __UM_PGTABLE_3LEVEL_H
 #define __UM_PGTABLE_3LEVEL_H
 
-#define __ARCH_USE_5LEVEL_HACK
 #include <asm-generic/pgtable-nopud.h>
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
index 36a44d5..2daa58d 100644 (file)
@@ -106,6 +106,9 @@ extern unsigned long end_iomem;
 #define pud_newpage(x)  (pud_val(x) & _PAGE_NEWPAGE)
 #define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEWPAGE)
 
+#define p4d_newpage(x)  (p4d_val(x) & _PAGE_NEWPAGE)
+#define p4d_mkuptodate(x) (p4d_val(x) &= ~_PAGE_NEWPAGE)
+
 #define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
 
 #define pte_page(x) pfn_to_page(pte_pfn(x))
index 417ff64..30885d0 100644 (file)
@@ -96,6 +96,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
                                 pgd_t *pgd_base)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        int i, j;
@@ -107,7 +108,8 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
        pgd = pgd_base + i;
 
        for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
-               pud = pud_offset(pgd, vaddr);
+               p4d = p4d_offset(pgd, vaddr);
+               pud = pud_offset(p4d, vaddr);
                if (pud_none(*pud))
                        one_md_table_init(pud);
                pmd = pmd_offset(pud, vaddr);
@@ -124,6 +126,7 @@ static void __init fixaddr_user_init( void)
 #ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
        long size = FIXADDR_USER_END - FIXADDR_USER_START;
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
@@ -144,7 +147,8 @@ static void __init fixaddr_user_init( void)
        for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE,
                      p += PAGE_SIZE) {
                pgd = swapper_pg_dir + pgd_index(vaddr);
-               pud = pud_offset(pgd, vaddr);
+               p4d = p4d_offset(pgd, vaddr);
+               pud = pud_offset(p4d, vaddr);
                pmd = pmd_offset(pud, vaddr);
                pte = pte_offset_kernel(pmd, vaddr);
                pte_set_val(*pte, p, PAGE_READONLY);
index b5e3d91..3f0d9a5 100644 (file)
@@ -19,15 +19,21 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
                         unsigned long kernel)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
 
        pgd = pgd_offset(mm, proc);
-       pud = pud_alloc(mm, pgd, proc);
-       if (!pud)
+
+       p4d = p4d_alloc(mm, pgd, proc);
+       if (!p4d)
                goto out;
 
+       pud = pud_alloc(mm, p4d, proc);
+       if (!pud)
+               goto out_pud;
+
        pmd = pmd_alloc(mm, pud, proc);
        if (!pmd)
                goto out_pmd;
@@ -44,6 +50,8 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
        pmd_free(mm, pmd);
  out_pmd:
        pud_free(mm, pud);
+ out_pud:
+       p4d_free(mm, p4d);
  out:
        return -ENOMEM;
 }
index 3236052..d617f8d 100644 (file)
@@ -17,6 +17,7 @@
 pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
 
@@ -27,7 +28,11 @@ pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr)
        if (!pgd_present(*pgd))
                return NULL;
 
-       pud = pud_offset(pgd, addr);
+       p4d = p4d_offset(pgd, addr);
+       if (!p4d_present(*p4d))
+               return NULL;
+
+       pud = pud_offset(p4d, addr);
        if (!pud_present(*pud))
                return NULL;
 
index b7eaf65..80a358c 100644 (file)
@@ -277,7 +277,7 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr,
        return ret;
 }
 
-static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
+static inline int update_pud_range(p4d_t *p4d, unsigned long addr,
                                   unsigned long end,
                                   struct host_vm_change *hvc)
 {
@@ -285,7 +285,7 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
        unsigned long next;
        int ret = 0;
 
-       pud = pud_offset(pgd, addr);
+       pud = pud_offset(p4d, addr);
        do {
                next = pud_addr_end(addr, end);
                if (!pud_present(*pud)) {
@@ -299,6 +299,28 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
        return ret;
 }
 
+static inline int update_p4d_range(pgd_t *pgd, unsigned long addr,
+                                  unsigned long end,
+                                  struct host_vm_change *hvc)
+{
+       p4d_t *p4d;
+       unsigned long next;
+       int ret = 0;
+
+       p4d = p4d_offset(pgd, addr);
+       do {
+               next = p4d_addr_end(addr, end);
+               if (!p4d_present(*p4d)) {
+                       if (hvc->force || p4d_newpage(*p4d)) {
+                               ret = add_munmap(addr, next - addr, hvc);
+                               p4d_mkuptodate(*p4d);
+                       }
+               } else
+                       ret = update_pud_range(p4d, addr, next, hvc);
+       } while (p4d++, addr = next, ((addr < end) && !ret));
+       return ret;
+}
+
 void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
                      unsigned long end_addr, int force)
 {
@@ -316,8 +338,8 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
                                ret = add_munmap(addr, next - addr, &hvc);
                                pgd_mkuptodate(*pgd);
                        }
-               }
-               else ret = update_pud_range(pgd, addr, next, &hvc);
+               } else
+                       ret = update_p4d_range(pgd, addr, next, &hvc);
        } while (pgd++, addr = next, ((addr < end_addr) && !ret));
 
        if (!ret)
@@ -338,6 +360,7 @@ static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
 {
        struct mm_struct *mm;
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
@@ -364,7 +387,23 @@ static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
                        continue;
                }
 
-               pud = pud_offset(pgd, addr);
+               p4d = p4d_offset(pgd, addr);
+               if (!p4d_present(*p4d)) {
+                       last = ADD_ROUND(addr, P4D_SIZE);
+                       if (last > end)
+                               last = end;
+                       if (p4d_newpage(*p4d)) {
+                               updated = 1;
+                               err = add_munmap(addr, last - addr, &hvc);
+                               if (err < 0)
+                                       panic("munmap failed, errno = %d\n",
+                                             -err);
+                       }
+                       addr = last;
+                       continue;
+               }
+
+               pud = pud_offset(p4d, addr);
                if (!pud_present(*pud)) {
                        last = ADD_ROUND(addr, PUD_SIZE);
                        if (last > end)
@@ -424,6 +463,7 @@ static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
 {
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
@@ -437,7 +477,11 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
        if (!pgd_present(*pgd))
                goto kill;
 
-       pud = pud_offset(pgd, address);
+       p4d = p4d_offset(pgd, address);
+       if (!p4d_present(*p4d))
+               goto kill;
+
+       pud = pud_offset(p4d, address);
        if (!pud_present(*pud))
                goto kill;
 
@@ -490,35 +534,6 @@ kill:
        force_sig(SIGKILL);
 }
 
-pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
-{
-       return pgd_offset(mm, address);
-}
-
-pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
-{
-       return pud_offset(pgd, address);
-}
-
-pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
-{
-       return pmd_offset(pud, address);
-}
-
-pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
-{
-       return pte_offset_kernel(pmd, address);
-}
-
-pte_t *addr_pte(struct task_struct *task, unsigned long addr)
-{
-       pgd_t *pgd = pgd_offset(task->mm, addr);
-       pud_t *pud = pud_offset(pgd, addr);
-       pmd_t *pmd = pmd_offset(pud, addr);
-
-       return pte_offset_map(pmd, addr);
-}
-
 void flush_tlb_all(void)
 {
        /*
index e62296c..8185530 100644 (file)
@@ -28,6 +28,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        pgd_t *pgd;
+       p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
@@ -104,7 +105,8 @@ good_area:
                }
 
                pgd = pgd_offset(mm, address);
-               pud = pud_offset(pgd, address);
+               p4d = p4d_offset(pgd, address);
+               pud = pud_offset(p4d, address);
                pmd = pmd_offset(pud, address);
                pte = pte_offset_kernel(pmd, address);
        } while (!pte_present(*pte));
index 7d1f6a4..062cdec 100644 (file)
@@ -388,7 +388,9 @@ static __always_inline int fls64(__u64 x)
 
 #include <asm-generic/bitops/const_hweight.h>
 
-#include <asm-generic/bitops-instrumented.h>
+#include <asm-generic/bitops/instrumented-atomic.h>
+#include <asm-generic/bitops/instrumented-non-atomic.h>
+#include <asm-generic/bitops/instrumented-lock.h>
 
 #include <asm-generic/bitops/le.h>
 
index 7c5bb43..b3d0664 100644 (file)
@@ -5,6 +5,9 @@
 #if !defined(__x86_64__) || !defined(__ILP32__)
 #include <asm-generic/msgbuf.h>
 #else
+
+#include <asm/ipcbuf.h>
+
 /*
  * The msqid64_ds structure for x86 architecture with x32 ABI.
  *
index 93030e9..71205b0 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_SEMBUF_H
 #define _ASM_X86_SEMBUF_H
 
+#include <asm/ipcbuf.h>
+
 /*
  * The semid64_ds structure for x86 architecture.
  * Note extra padding because this structure is passed back and forth
index 319be93..fa31470 100644 (file)
@@ -259,7 +259,7 @@ static void __init setup_xstate_features(void)
                                                   xmm_space);
 
        xstate_offsets[XFEATURE_SSE]    = xstate_sizes[XFEATURE_FP];
-       xstate_sizes[XFEATURE_SSE]      = FIELD_SIZEOF(struct fxregs_state,
+       xstate_sizes[XFEATURE_SSE]      = sizeof_field(struct fxregs_state,
                                                       xmm_space);
 
        for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
index 060a361..024c305 100644 (file)
@@ -1043,20 +1043,6 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
                return;
 
        /*
-        * If the return location is actually pointing directly to
-        * the start of a direct trampoline (if we trace the trampoline
-        * it will still be offset by MCOUNT_INSN_SIZE), then the
-        * return address is actually off by one word, and we
-        * need to adjust for that.
-        */
-       if (ftrace_direct_func_count) {
-               if (ftrace_find_direct_func(self_addr + MCOUNT_INSN_SIZE)) {
-                       self_addr = *parent;
-                       parent++;
-               }
-       }
-
-       /*
         * Protect against fault, even if it shouldn't
         * happen. This tool is too much intrusive to
         * ignore such a protection.
index c0aa074..cfafa32 100644 (file)
@@ -504,7 +504,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
 
        r = -E2BIG;
 
-       if (*nent >= maxnent)
+       if (WARN_ON(*nent >= maxnent))
                goto out;
 
        do_host_cpuid(entry, function, 0);
@@ -778,6 +778,11 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
        case 0x8000001a:
        case 0x8000001e:
                break;
+       /* Support memory encryption cpuid if host supports it */
+       case 0x8000001F:
+               if (!boot_cpu_has(X86_FEATURE_SEV))
+                       entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
+               break;
        /*Add support for Centaur's CPUID instruction*/
        case 0xC0000000:
                /*Just support up to 0xC0000004 now*/
@@ -810,6 +815,9 @@ out:
 static int do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 func,
                         int *nent, int maxnent, unsigned int type)
 {
+       if (*nent >= maxnent)
+               return -E2BIG;
+
        if (type == KVM_GET_EMULATED_CPUID)
                return __do_cpuid_func_emulated(entry, func, nent, maxnent);
 
index 362e874..122d4ce 100644 (file)
@@ -5958,13 +5958,6 @@ static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
                if (npt_enabled)
                        entry->edx |= F(NPT);
 
-               break;
-       case 0x8000001F:
-               /* Support memory encryption cpuid if host supports it */
-               if (boot_cpu_has(X86_FEATURE_SEV))
-                       cpuid(0x8000001f, &entry->eax, &entry->ebx,
-                               &entry->ecx, &entry->edx);
-
        }
 }
 
index 1b9ab41..e3394c8 100644 (file)
@@ -6666,7 +6666,6 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
        free_vpid(vmx->vpid);
        nested_vmx_free_vcpu(vcpu);
        free_loaded_vmcs(vmx->loaded_vmcs);
-       kfree(vmx->guest_msrs);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(x86_fpu_cache, vmx->vcpu.arch.user_fpu);
        kmem_cache_free(x86_fpu_cache, vmx->vcpu.arch.guest_fpu);
@@ -6723,12 +6722,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
                        goto uninit_vcpu;
        }
 
-       vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL_ACCOUNT);
-       BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) * sizeof(vmx->guest_msrs[0])
-                    > PAGE_SIZE);
-
-       if (!vmx->guest_msrs)
-               goto free_pml;
+       BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) != NR_SHARED_MSRS);
 
        for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) {
                u32 index = vmx_msr_index[i];
@@ -6760,7 +6754,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
 
        err = alloc_loaded_vmcs(&vmx->vmcs01);
        if (err < 0)
-               goto free_msrs;
+               goto free_pml;
 
        msr_bitmap = vmx->vmcs01.msr_bitmap;
        vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_TSC, MSR_TYPE_R);
@@ -6822,8 +6816,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
 
 free_vmcs:
        free_loaded_vmcs(vmx->loaded_vmcs);
-free_msrs:
-       kfree(vmx->guest_msrs);
 free_pml:
        vmx_destroy_pml_buffer(vmx);
 uninit_vcpu:
index 7c1b978..a4f7f73 100644 (file)
@@ -22,6 +22,12 @@ extern u32 get_umwait_control_msr(void);
 
 #define X2APIC_MSR(r) (APIC_BASE_MSR + ((r) >> 4))
 
+#ifdef CONFIG_X86_64
+#define NR_SHARED_MSRS 7
+#else
+#define NR_SHARED_MSRS 4
+#endif
+
 #define NR_LOADSTORE_MSRS 8
 
 struct vmx_msrs {
@@ -206,7 +212,7 @@ struct vcpu_vmx {
        u32                   idt_vectoring_info;
        ulong                 rflags;
 
-       struct shared_msr_entry *guest_msrs;
+       struct shared_msr_entry guest_msrs[NR_SHARED_MSRS];
        int                   nmsrs;
        int                   save_nmsrs;
        bool                  guest_msrs_ready;
index a57afa0..3bd0642 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef _XTENSA_IPCBUF_H
 #define _XTENSA_IPCBUF_H
 
+#include <linux/posix_types.h>
+
 /*
  * Pad space is left for:
  * - 32-bit mode_t and seq
index d6915e9..1ed2c85 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef _XTENSA_MSGBUF_H
 #define _XTENSA_MSGBUF_H
 
+#include <asm/ipcbuf.h>
+
 struct msqid64_ds {
        struct ipc64_perm msg_perm;
 #ifdef __XTENSA_EB__
index 09f348d..3b9cdd4 100644 (file)
@@ -22,6 +22,7 @@
 #define _XTENSA_SEMBUF_H
 
 #include <asm/byteorder.h>
+#include <asm/ipcbuf.h>
 
 struct semid64_ds {
        struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
index cea0ae1..e1419ed 100644 (file)
@@ -351,6 +351,9 @@ void bfqg_stats_update_legacy_io(struct request_queue *q, struct request *rq)
 {
        struct bfq_group *bfqg = blkg_to_bfqg(rq->bio->bi_blkg);
 
+       if (!bfqg)
+               return;
+
        blkg_rwstat_add(&bfqg->stats.bytes, rq->cmd_flags, blk_rq_bytes(rq));
        blkg_rwstat_add(&bfqg->stats.ios, rq->cmd_flags, 1);
 }
index fb95dbb..bf62c25 100644 (file)
@@ -87,7 +87,7 @@ EXPORT_SYMBOL(bio_integrity_alloc);
  * Description: Used to free the integrity portion of a bio. Usually
  * called from bio_free().
  */
-static void bio_integrity_free(struct bio *bio)
+void bio_integrity_free(struct bio *bio)
 {
        struct bio_integrity_payload *bip = bio_integrity(bio);
        struct bio_set *bs = bio->bi_pool;
index b1170ec..a5d75f6 100644 (file)
@@ -233,6 +233,9 @@ fallback:
 void bio_uninit(struct bio *bio)
 {
        bio_disassociate_blkg(bio);
+
+       if (bio_integrity(bio))
+               bio_integrity_free(bio);
 }
 EXPORT_SYMBOL(bio_uninit);
 
@@ -751,10 +754,12 @@ bool __bio_try_merge_page(struct bio *bio, struct page *page,
        if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
                return false;
 
-       if (bio->bi_vcnt > 0 && !bio_full(bio, len)) {
+       if (bio->bi_vcnt > 0) {
                struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
 
                if (page_is_mergeable(bv, page, len, off, same_page)) {
+                       if (bio->bi_iter.bi_size > UINT_MAX - len)
+                               return false;
                        bv->bv_len += len;
                        bio->bi_iter.bi_size += len;
                        return true;
index 708dea9..a229b94 100644 (file)
@@ -1062,26 +1062,6 @@ err_unlock:
 }
 
 /**
- * blkcg_drain_queue - drain blkcg part of request_queue
- * @q: request_queue to drain
- *
- * Called from blk_drain_queue().  Responsible for draining blkcg part.
- */
-void blkcg_drain_queue(struct request_queue *q)
-{
-       lockdep_assert_held(&q->queue_lock);
-
-       /*
-        * @q could be exiting and already have destroyed all blkgs as
-        * indicated by NULL root_blkg.  If so, don't confuse policies.
-        */
-       if (!q->root_blkg)
-               return;
-
-       blk_throtl_drain(q);
-}
-
-/**
  * blkcg_exit_queue - exit and release blkcg part of request_queue
  * @q: request_queue being released
  *
index a1e2287..e0a094f 100644 (file)
@@ -1310,7 +1310,7 @@ EXPORT_SYMBOL_GPL(blk_rq_err_bytes);
 
 void blk_account_io_completion(struct request *req, unsigned int bytes)
 {
-       if (blk_do_io_stat(req)) {
+       if (req->part && blk_do_io_stat(req)) {
                const int sgrp = op_stat_group(req_op(req));
                struct hd_struct *part;
 
@@ -1328,7 +1328,8 @@ void blk_account_io_done(struct request *req, u64 now)
         * normal IO on queueing nor completion.  Accounting the
         * containing request is enough.
         */
-       if (blk_do_io_stat(req) && !(req->rq_flags & RQF_FLUSH_SEQ)) {
+       if (req->part && blk_do_io_stat(req) &&
+           !(req->rq_flags & RQF_FLUSH_SEQ)) {
                const int sgrp = op_stat_group(req_op(req));
                struct hd_struct *part;
 
@@ -1792,9 +1793,9 @@ int __init blk_dev_init(void)
 {
        BUILD_BUG_ON(REQ_OP_LAST >= (1 << REQ_OP_BITS));
        BUILD_BUG_ON(REQ_OP_BITS + REQ_FLAG_BITS > 8 *
-                       FIELD_SIZEOF(struct request, cmd_flags));
+                       sizeof_field(struct request, cmd_flags));
        BUILD_BUG_ON(REQ_OP_BITS + REQ_FLAG_BITS > 8 *
-                       FIELD_SIZEOF(struct bio, bi_opf));
+                       sizeof_field(struct bio, bi_opf));
 
        /* used for unplugging and affects IO latency/throughput - HIGHPRI */
        kblockd_workqueue = alloc_workqueue("kblockd",
index 6fad6f3..d00fcfd 100644 (file)
@@ -70,30 +70,20 @@ void __blk_req_zone_write_unlock(struct request *rq)
 }
 EXPORT_SYMBOL_GPL(__blk_req_zone_write_unlock);
 
-static inline unsigned int __blkdev_nr_zones(struct request_queue *q,
-                                            sector_t nr_sectors)
-{
-       sector_t zone_sectors = blk_queue_zone_sectors(q);
-
-       return (nr_sectors + zone_sectors - 1) >> ilog2(zone_sectors);
-}
-
 /**
  * blkdev_nr_zones - Get number of zones
- * @bdev:      Target block device
+ * @disk:      Target gendisk
  *
- * Description:
- *    Return the total number of zones of a zoned block device.
- *    For a regular block device, the number of zones is always 0.
+ * Return the total number of zones of a zoned block device.  For a block
+ * device without zone capabilities, the number of zones is always 0.
  */
-unsigned int blkdev_nr_zones(struct block_device *bdev)
+unsigned int blkdev_nr_zones(struct gendisk *disk)
 {
-       struct request_queue *q = bdev_get_queue(bdev);
+       sector_t zone_sectors = blk_queue_zone_sectors(disk->queue);
 
-       if (!blk_queue_is_zoned(q))
+       if (!blk_queue_is_zoned(disk->queue))
                return 0;
-
-       return __blkdev_nr_zones(q, get_capacity(bdev->bd_disk));
+       return (get_capacity(disk) + zone_sectors - 1) >> ilog2(zone_sectors);
 }
 EXPORT_SYMBOL_GPL(blkdev_nr_zones);
 
@@ -342,16 +332,18 @@ static inline unsigned long *blk_alloc_zone_bitmap(int node,
 
 void blk_queue_free_zone_bitmaps(struct request_queue *q)
 {
-       kfree(q->seq_zones_bitmap);
-       q->seq_zones_bitmap = NULL;
+       kfree(q->conv_zones_bitmap);
+       q->conv_zones_bitmap = NULL;
        kfree(q->seq_zones_wlock);
        q->seq_zones_wlock = NULL;
 }
 
 struct blk_revalidate_zone_args {
        struct gendisk  *disk;
-       unsigned long   *seq_zones_bitmap;
+       unsigned long   *conv_zones_bitmap;
        unsigned long   *seq_zones_wlock;
+       unsigned int    nr_zones;
+       sector_t        zone_sectors;
        sector_t        sector;
 };
 
@@ -364,25 +356,33 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
        struct blk_revalidate_zone_args *args = data;
        struct gendisk *disk = args->disk;
        struct request_queue *q = disk->queue;
-       sector_t zone_sectors = blk_queue_zone_sectors(q);
        sector_t capacity = get_capacity(disk);
 
        /*
         * All zones must have the same size, with the exception on an eventual
         * smaller last zone.
         */
-       if (zone->start + zone_sectors < capacity &&
-           zone->len != zone_sectors) {
-               pr_warn("%s: Invalid zoned device with non constant zone size\n",
-                       disk->disk_name);
-               return false;
-       }
+       if (zone->start == 0) {
+               if (zone->len == 0 || !is_power_of_2(zone->len)) {
+                       pr_warn("%s: Invalid zoned device with non power of two zone size (%llu)\n",
+                               disk->disk_name, zone->len);
+                       return -ENODEV;
+               }
 
-       if (zone->start + zone->len >= capacity &&
-           zone->len > zone_sectors) {
-               pr_warn("%s: Invalid zoned device with larger last zone size\n",
-                       disk->disk_name);
-               return -ENODEV;
+               args->zone_sectors = zone->len;
+               args->nr_zones = (capacity + zone->len - 1) >> ilog2(zone->len);
+       } else if (zone->start + args->zone_sectors < capacity) {
+               if (zone->len != args->zone_sectors) {
+                       pr_warn("%s: Invalid zoned device with non constant zone size\n",
+                               disk->disk_name);
+                       return -ENODEV;
+               }
+       } else {
+               if (zone->len > args->zone_sectors) {
+                       pr_warn("%s: Invalid zoned device with larger last zone size\n",
+                               disk->disk_name);
+                       return -ENODEV;
+               }
        }
 
        /* Check for holes in the zone report */
@@ -395,8 +395,22 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
        /* Check zone type */
        switch (zone->type) {
        case BLK_ZONE_TYPE_CONVENTIONAL:
+               if (!args->conv_zones_bitmap) {
+                       args->conv_zones_bitmap =
+                               blk_alloc_zone_bitmap(q->node, args->nr_zones);
+                       if (!args->conv_zones_bitmap)
+                               return -ENOMEM;
+               }
+               set_bit(idx, args->conv_zones_bitmap);
+               break;
        case BLK_ZONE_TYPE_SEQWRITE_REQ:
        case BLK_ZONE_TYPE_SEQWRITE_PREF:
+               if (!args->seq_zones_wlock) {
+                       args->seq_zones_wlock =
+                               blk_alloc_zone_bitmap(q->node, args->nr_zones);
+                       if (!args->seq_zones_wlock)
+                               return -ENOMEM;
+               }
                break;
        default:
                pr_warn("%s: Invalid zone type 0x%x at sectors %llu\n",
@@ -404,78 +418,54 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
                return -ENODEV;
        }
 
-       if (zone->type != BLK_ZONE_TYPE_CONVENTIONAL)
-               set_bit(idx, args->seq_zones_bitmap);
-
        args->sector += zone->len;
        return 0;
 }
 
-static int blk_update_zone_info(struct gendisk *disk, unsigned int nr_zones,
-                               struct blk_revalidate_zone_args *args)
-{
-       /*
-        * Ensure that all memory allocations in this context are done as
-        * if GFP_NOIO was specified.
-        */
-       unsigned int noio_flag = memalloc_noio_save();
-       struct request_queue *q = disk->queue;
-       int ret;
-
-       args->seq_zones_wlock = blk_alloc_zone_bitmap(q->node, nr_zones);
-       if (!args->seq_zones_wlock)
-               return -ENOMEM;
-       args->seq_zones_bitmap = blk_alloc_zone_bitmap(q->node, nr_zones);
-       if (!args->seq_zones_bitmap)
-               return -ENOMEM;
-
-       ret = disk->fops->report_zones(disk, 0, nr_zones,
-                                      blk_revalidate_zone_cb, args);
-       memalloc_noio_restore(noio_flag);
-       return ret;
-}
-
 /**
  * blk_revalidate_disk_zones - (re)allocate and initialize zone bitmaps
  * @disk:      Target disk
  *
  * Helper function for low-level device drivers to (re) allocate and initialize
  * a disk request queue zone bitmaps. This functions should normally be called
- * within the disk ->revalidate method. For BIO based queues, no zone bitmap
- * is allocated.
+ * within the disk ->revalidate method for blk-mq based drivers.  For BIO based
+ * drivers only q->nr_zones needs to be updated so that the sysfs exposed value
+ * is correct.
  */
 int blk_revalidate_disk_zones(struct gendisk *disk)
 {
        struct request_queue *q = disk->queue;
-       unsigned int nr_zones = __blkdev_nr_zones(q, get_capacity(disk));
-       struct blk_revalidate_zone_args args = { .disk = disk };
-       int ret = 0;
+       struct blk_revalidate_zone_args args = {
+               .disk           = disk,
+       };
+       unsigned int noio_flag;
+       int ret;
 
        if (WARN_ON_ONCE(!blk_queue_is_zoned(q)))
                return -EIO;
+       if (WARN_ON_ONCE(!queue_is_mq(q)))
+               return -EIO;
 
        /*
-        * BIO based queues do not use a scheduler so only q->nr_zones
-        * needs to be updated so that the sysfs exposed value is correct.
+        * Ensure that all memory allocations in this context are done as if
+        * GFP_NOIO was specified.
         */
-       if (!queue_is_mq(q)) {
-               q->nr_zones = nr_zones;
-               return 0;
-       }
-
-       if (nr_zones)
-               ret = blk_update_zone_info(disk, nr_zones, &args);
+       noio_flag = memalloc_noio_save();
+       ret = disk->fops->report_zones(disk, 0, UINT_MAX,
+                                      blk_revalidate_zone_cb, &args);
+       memalloc_noio_restore(noio_flag);
 
        /*
-        * Install the new bitmaps, making sure the queue is stopped and
-        * all I/Os are completed (i.e. a scheduler is not referencing the
-        * bitmaps).
+        * Install the new bitmaps and update nr_zones only once the queue is
+        * stopped and all I/Os are completed (i.e. a scheduler is not
+        * referencing the bitmaps).
         */
        blk_mq_freeze_queue(q);
        if (ret >= 0) {
-               q->nr_zones = nr_zones;
+               blk_queue_chunk_sectors(q, args.zone_sectors);
+               q->nr_zones = args.nr_zones;
                swap(q->seq_zones_wlock, args.seq_zones_wlock);
-               swap(q->seq_zones_bitmap, args.seq_zones_bitmap);
+               swap(q->conv_zones_bitmap, args.conv_zones_bitmap);
                ret = 0;
        } else {
                pr_warn("%s: failed to revalidate zones\n", disk->disk_name);
@@ -484,8 +474,7 @@ int blk_revalidate_disk_zones(struct gendisk *disk)
        blk_mq_unfreeze_queue(q);
 
        kfree(args.seq_zones_wlock);
-       kfree(args.seq_zones_bitmap);
+       kfree(args.conv_zones_bitmap);
        return ret;
 }
 EXPORT_SYMBOL_GPL(blk_revalidate_disk_zones);
-
index 2bea401..6842f28 100644 (file)
@@ -121,6 +121,7 @@ static inline void blk_rq_bio_prep(struct request *rq, struct bio *bio,
 #ifdef CONFIG_BLK_DEV_INTEGRITY
 void blk_flush_integrity(void);
 bool __bio_integrity_endio(struct bio *);
+void bio_integrity_free(struct bio *bio);
 static inline bool bio_integrity_endio(struct bio *bio)
 {
        if (bio_integrity(bio))
@@ -166,6 +167,9 @@ static inline bool bio_integrity_endio(struct bio *bio)
 {
        return true;
 }
+static inline void bio_integrity_free(struct bio *bio)
+{
+}
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
 unsigned long blk_rq_timeout(unsigned long timeout);
index 7ac8a66..5de98b9 100644 (file)
@@ -512,7 +512,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
        case BLKGETZONESZ:
                return put_uint(arg, bdev_zone_sectors(bdev));
        case BLKGETNRZONES:
-               return put_uint(arg, blkdev_nr_zones(bdev));
+               return put_uint(arg, blkdev_nr_zones(bdev->bd_disk));
        case HDIO_GETGEO:
                return blkdev_getgeo(bdev, argp);
        case BLKRAGET:
index aded260..9dc53cf 100644 (file)
@@ -436,10 +436,10 @@ static int adiantum_init_tfm(struct crypto_skcipher *tfm)
 
        BUILD_BUG_ON(offsetofend(struct adiantum_request_ctx, u) !=
                     sizeof(struct adiantum_request_ctx));
-       subreq_size = max(FIELD_SIZEOF(struct adiantum_request_ctx,
+       subreq_size = max(sizeof_field(struct adiantum_request_ctx,
                                       u.hash_desc) +
                          crypto_shash_descsize(hash),
-                         FIELD_SIZEOF(struct adiantum_request_ctx,
+                         sizeof_field(struct adiantum_request_ctx,
                                       u.streamcipher_req) +
                          crypto_skcipher_reqsize(streamcipher));
 
index 808f2b3..495a2d1 100644 (file)
@@ -347,7 +347,7 @@ static int essiv_aead_init_tfm(struct crypto_aead *tfm)
        if (IS_ERR(aead))
                return PTR_ERR(aead);
 
-       subreq_size = FIELD_SIZEOF(struct essiv_aead_request_ctx, aead_req) +
+       subreq_size = sizeof_field(struct essiv_aead_request_ctx, aead_req) +
                      crypto_aead_reqsize(aead);
 
        tctx->ivoffset = offsetof(struct essiv_aead_request_ctx, aead_req) +
index 4fb9751..002838d 100644 (file)
@@ -104,9 +104,9 @@ config ACPI_PROCFS_POWER
        depends on X86 && PROC_FS
        help
          For backwards compatibility, this option allows
-          deprecated power /proc/acpi/ directories to exist, even when
-          they have been replaced by functions in /sys.
-          The deprecated directories (and their replacements) include:
+         deprecated power /proc/acpi/ directories to exist, even when
+         they have been replaced by functions in /sys.
+         The deprecated directories (and their replacements) include:
          /proc/acpi/battery/* (/sys/class/power_supply/*) and
          /proc/acpi/ac_adapter/* (sys/class/power_supply/*).
          This option has no effect on /proc/acpi/ directories
@@ -448,7 +448,7 @@ config ACPI_CUSTOM_METHOD
 config ACPI_BGRT
        bool "Boottime Graphics Resource Table support"
        depends on EFI && (X86 || ARM64)
-        help
+       help
          This driver adds support for exposing the ACPI Boottime Graphics
          Resource Table, which allows the operating system to obtain
          data from the firmware boot splash. It will appear under
index 48bc96d..5400267 100644 (file)
@@ -153,7 +153,7 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data)
 {
        acpi_status status;
 
-       if (!*data)
+       if (!data)
                return -EINVAL;
 
        status = acpi_get_data(handle, acpi_bus_private_data_handler, data);
index d27b01c..b758b45 100644 (file)
@@ -79,6 +79,19 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
 static const struct dmi_system_id dmi_lid_quirks[] = {
        {
                /*
+                * Acer Switch 10 SW5-012. _LID method messes with home and
+                * power button GPIO IRQ settings causing an interrupt storm on
+                * both GPIOs. This is unfixable without a DSDT override, so we
+                * have to disable the lid-switch functionality altogether :|
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+               },
+               .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
+       },
+       {
+               /*
                 * Asus T200TA, _LID keeps reporting closed after every second
                 * openening of the lid. Causing immediate re-suspend after
                 * opening every other open. Using LID_INIT_OPEN fixes this.
index 08bb9f2..5e4a886 100644 (file)
@@ -1314,9 +1314,19 @@ static void acpi_dev_pm_detach(struct device *dev, bool power_off)
  */
 int acpi_dev_pm_attach(struct device *dev, bool power_on)
 {
+       /*
+        * Skip devices whose ACPI companions match the device IDs below,
+        * because they require special power management handling incompatible
+        * with the generic ACPI PM domain.
+        */
+       static const struct acpi_device_id special_pm_ids[] = {
+               {"PNP0C0B", }, /* Generic ACPI fan */
+               {"INT3404", }, /* Fan */
+               {}
+       };
        struct acpi_device *adev = ACPI_COMPANION(dev);
 
-       if (!adev)
+       if (!adev || !acpi_match_device_ids(adev, special_pm_ids))
                return 0;
 
        /*
index 4fd84fb..d05be13 100644 (file)
@@ -533,26 +533,10 @@ static void acpi_ec_enable_event(struct acpi_ec *ec)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static bool acpi_ec_query_flushed(struct acpi_ec *ec)
+static void __acpi_ec_flush_work(void)
 {
-       bool flushed;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ec->lock, flags);
-       flushed = !ec->nr_pending_queries;
-       spin_unlock_irqrestore(&ec->lock, flags);
-       return flushed;
-}
-
-static void __acpi_ec_flush_event(struct acpi_ec *ec)
-{
-       /*
-        * When ec_freeze_events is true, we need to flush events in
-        * the proper position before entering the noirq stage.
-        */
-       wait_event(ec->wait, acpi_ec_query_flushed(ec));
-       if (ec_query_wq)
-               flush_workqueue(ec_query_wq);
+       flush_scheduled_work(); /* flush ec->work */
+       flush_workqueue(ec_query_wq); /* flush queries */
 }
 
 static void acpi_ec_disable_event(struct acpi_ec *ec)
@@ -562,15 +546,21 @@ static void acpi_ec_disable_event(struct acpi_ec *ec)
        spin_lock_irqsave(&ec->lock, flags);
        __acpi_ec_disable_event(ec);
        spin_unlock_irqrestore(&ec->lock, flags);
-       __acpi_ec_flush_event(ec);
+
+       /*
+        * When ec_freeze_events is true, we need to flush events in
+        * the proper position before entering the noirq stage.
+        */
+       __acpi_ec_flush_work();
 }
 
 void acpi_ec_flush_work(void)
 {
-       if (first_ec)
-               __acpi_ec_flush_event(first_ec);
+       /* Without ec_query_wq there is nothing to flush. */
+       if (!ec_query_wq)
+               return;
 
-       flush_scheduled_work();
+       __acpi_ec_flush_work();
 }
 #endif /* CONFIG_PM_SLEEP */
 
index a2e844a..41168c0 100644 (file)
@@ -374,19 +374,21 @@ void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
-static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
+/* Must be called with mutex_lock(&acpi_ioremap_lock) */
+static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map)
 {
-       if (!--map->refcount)
+       unsigned long refcount = --map->refcount;
+
+       if (!refcount)
                list_del_rcu(&map->list);
+       return refcount;
 }
 
 static void acpi_os_map_cleanup(struct acpi_ioremap *map)
 {
-       if (!map->refcount) {
-               synchronize_rcu_expedited();
-               acpi_unmap(map->phys, map->virt);
-               kfree(map);
-       }
+       synchronize_rcu_expedited();
+       acpi_unmap(map->phys, map->virt);
+       kfree(map);
 }
 
 /**
@@ -406,6 +408,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
 void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
 {
        struct acpi_ioremap *map;
+       unsigned long refcount;
 
        if (!acpi_permanent_mmap) {
                __acpi_unmap_table(virt, size);
@@ -419,10 +422,11 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
                WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
                return;
        }
-       acpi_os_drop_map_ref(map);
+       refcount = acpi_os_drop_map_ref(map);
        mutex_unlock(&acpi_ioremap_lock);
 
-       acpi_os_map_cleanup(map);
+       if (!refcount)
+               acpi_os_map_cleanup(map);
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
 
@@ -457,6 +461,7 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
 {
        u64 addr;
        struct acpi_ioremap *map;
+       unsigned long refcount;
 
        if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
                return;
@@ -472,10 +477,11 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
                mutex_unlock(&acpi_ioremap_lock);
                return;
        }
-       acpi_os_drop_map_ref(map);
+       refcount = acpi_os_drop_map_ref(map);
        mutex_unlock(&acpi_ioremap_lock);
 
-       acpi_os_map_cleanup(map);
+       if (!refcount)
+               acpi_os_map_cleanup(map);
 }
 EXPORT_SYMBOL(acpi_os_unmap_generic_address);
 
index 2af937a..6747a27 100644 (file)
@@ -977,6 +977,16 @@ static int acpi_s2idle_prepare_late(void)
        return 0;
 }
 
+static void acpi_s2idle_sync(void)
+{
+       /*
+        * The EC driver uses the system workqueue and an additional special
+        * one, so those need to be flushed too.
+        */
+       acpi_ec_flush_work();
+       acpi_os_wait_events_complete(); /* synchronize Notify handling */
+}
+
 static void acpi_s2idle_wake(void)
 {
        /*
@@ -1001,13 +1011,8 @@ static void acpi_s2idle_wake(void)
                 * should be missed by canceling the wakeup here.
                 */
                pm_system_cancel_wakeup();
-               /*
-                * The EC driver uses the system workqueue and an additional
-                * special one, so those need to be flushed too.
-                */
-               acpi_os_wait_events_complete(); /* synchronize EC GPE processing */
-               acpi_ec_flush_work();
-               acpi_os_wait_events_complete(); /* synchronize Notify handling */
+
+               acpi_s2idle_sync();
 
                rearm_wake_irq(acpi_sci_irq);
        }
@@ -1024,6 +1029,13 @@ static void acpi_s2idle_restore_early(void)
 
 static void acpi_s2idle_restore(void)
 {
+       /*
+        * Drain pending events before restoring the working-state configuration
+        * of GPEs.
+        */
+       acpi_os_wait_events_complete(); /* synchronize GPE processing */
+       acpi_s2idle_sync();
+
        s2idle_wakeup = false;
 
        acpi_enable_all_runtime_gpes();
index 75948a3..c60d2c6 100644 (file)
@@ -819,14 +819,14 @@ end:
  * interface:
  *   echo unmask > /sys/firmware/acpi/interrupts/gpe00
  */
-#define ACPI_MASKABLE_GPE_MAX  0xFF
+#define ACPI_MASKABLE_GPE_MAX  0x100
 static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata;
 
 static int __init acpi_gpe_set_masked_gpes(char *val)
 {
        u8 gpe;
 
-       if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX)
+       if (kstrtou8(val, 0, &gpe))
                return -EINVAL;
        set_bit(gpe, acpi_masked_gpes_map);
 
@@ -838,7 +838,7 @@ void __init acpi_gpe_apply_masked_gpes(void)
 {
        acpi_handle handle;
        acpi_status status;
-       u8 gpe;
+       u16 gpe;
 
        for_each_set_bit(gpe, acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) {
                status = acpi_get_gpe_device(gpe, &handle);
index e9bc9fc..b2dad43 100644 (file)
@@ -3310,7 +3310,7 @@ static void binder_transaction(struct binder_proc *proc,
                        binder_size_t parent_offset;
                        struct binder_fd_array_object *fda =
                                to_binder_fd_array_object(hdr);
-                       size_t num_valid = (buffer_offset - off_start_offset) *
+                       size_t num_valid = (buffer_offset - off_start_offset) /
                                                sizeof(binder_size_t);
                        struct binder_buffer_object *parent =
                                binder_validate_ptr(target_proc, t->buffer,
@@ -3384,7 +3384,7 @@ static void binder_transaction(struct binder_proc *proc,
                                t->buffer->user_data + sg_buf_offset;
                        sg_buf_offset += ALIGN(bp->length, sizeof(u64));
 
-                       num_valid = (buffer_offset - off_start_offset) *
+                       num_valid = (buffer_offset - off_start_offset) /
                                        sizeof(binder_size_t);
                        ret = binder_fixup_parent(t, thread, bp,
                                                  off_start_offset,
index bef6b85..874c259 100644 (file)
@@ -288,31 +288,6 @@ static int charlcd_init_display(struct charlcd *lcd)
 }
 
 /*
- * Parses an unsigned integer from a string, until a non-digit character
- * is found. The empty string is not accepted. No overflow checks are done.
- *
- * Returns whether the parsing was successful. Only in that case
- * the output parameters are written to.
- *
- * TODO: If the kernel adds an inplace version of kstrtoul(), this function
- * could be easily replaced by that.
- */
-static bool parse_n(const char *s, unsigned long *res, const char **next_s)
-{
-       if (!isdigit(*s))
-               return false;
-
-       *res = 0;
-       while (isdigit(*s)) {
-               *res = *res * 10 + (*s - '0');
-               ++s;
-       }
-
-       *next_s = s;
-       return true;
-}
-
-/*
  * Parses a movement command of the form "(.*);", where the group can be
  * any number of subcommands of the form "(x|y)[0-9]+".
  *
@@ -336,6 +311,7 @@ static bool parse_xy(const char *s, unsigned long *x, unsigned long *y)
 {
        unsigned long new_x = *x;
        unsigned long new_y = *y;
+       char *p;
 
        for (;;) {
                if (!*s)
@@ -345,11 +321,15 @@ static bool parse_xy(const char *s, unsigned long *x, unsigned long *y)
                        break;
 
                if (*s == 'x') {
-                       if (!parse_n(s + 1, &new_x, &s))
+                       new_x = simple_strtoul(s + 1, &p, 10);
+                       if (p == s + 1)
                                return false;
+                       s = p;
                } else if (*s == 'y') {
-                       if (!parse_n(s + 1, &new_y, &s))
+                       new_y = simple_strtoul(s + 1, &p, 10);
+                       if (p == s + 1)
                                return false;
+                       s = p;
                } else {
                        return false;
                }
index 28b92e3..c3b3b5c 100644 (file)
@@ -148,6 +148,10 @@ config DEBUG_TEST_DRIVER_REMOVE
          unusable. You should say N here unless you are explicitly looking to
          test this functionality.
 
+config PM_QOS_KUNIT_TEST
+       bool "KUnit Test for PM QoS features"
+       depends on KUNIT
+
 config HMEM_REPORTING
        bool
        default n
index 30d0523..6cdbf15 100644 (file)
@@ -359,7 +359,7 @@ static int handle_remove(const char *nodename, struct device *dev)
  * If configured, or requested by the commandline, devtmpfs will be
  * auto-mounted after the kernel mounted the root filesystem.
  */
-int devtmpfs_mount(const char *mntdir)
+int devtmpfs_mount(void)
 {
        int err;
 
@@ -369,7 +369,7 @@ int devtmpfs_mount(const char *mntdir)
        if (!thread)
                return 0;
 
-       err = ksys_mount("devtmpfs", mntdir, "devtmpfs", MS_SILENT, NULL);
+       err = do_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
        if (err)
                printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
        else
@@ -394,7 +394,7 @@ static int devtmpfsd(void *p)
        *err = ksys_unshare(CLONE_NEWNS);
        if (*err)
                goto out;
-       *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
+       *err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
        if (*err)
                goto out;
        ksys_chdir("/.."); /* will traverse into overmounted root */
index 296546f..98a31ba 100644 (file)
@@ -496,20 +496,17 @@ static ssize_t node_read_vmstat(struct device *dev,
        int n = 0;
 
        for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
-               n += sprintf(buf+n, "%s %lu\n", vmstat_text[i],
+               n += sprintf(buf+n, "%s %lu\n", zone_stat_name(i),
                             sum_zone_node_page_state(nid, i));
 
 #ifdef CONFIG_NUMA
        for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
-               n += sprintf(buf+n, "%s %lu\n",
-                            vmstat_text[i + NR_VM_ZONE_STAT_ITEMS],
+               n += sprintf(buf+n, "%s %lu\n", numa_stat_name(i),
                             sum_zone_numa_state(nid, i));
 #endif
 
        for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
-               n += sprintf(buf+n, "%s %lu\n",
-                            vmstat_text[i + NR_VM_ZONE_STAT_ITEMS +
-                            NR_VM_NUMA_STAT_ITEMS],
+               n += sprintf(buf+n, "%s %lu\n", node_stat_name(i),
                             node_page_state(pgdat, i));
 
        return n;
index 7c53254..cf6b6b7 100644 (file)
@@ -1325,10 +1325,14 @@ struct device *platform_find_device_by_driver(struct device *start,
 }
 EXPORT_SYMBOL_GPL(platform_find_device_by_driver);
 
+void __weak __init early_platform_cleanup(void) { }
+
 int __init platform_bus_init(void)
 {
        int error;
 
+       early_platform_cleanup();
+
        error = device_register(&platform_bus);
        if (error) {
                put_device(&platform_bus);
index ec5bb19..8fdd007 100644 (file)
@@ -4,5 +4,6 @@ obj-$(CONFIG_PM_SLEEP)  += main.o wakeup.o wakeup_stats.o
 obj-$(CONFIG_PM_TRACE_RTC)     += trace.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS)       +=  domain.o domain_governor.o
 obj-$(CONFIG_HAVE_CLK) += clock_ops.o
+obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
diff --git a/drivers/base/power/qos-test.c b/drivers/base/power/qos-test.c
new file mode 100644 (file)
index 0000000..3115db0
--- /dev/null
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP
+ */
+#include <kunit/test.h>
+#include <linux/pm_qos.h>
+
+/* Basic test for aggregating two "min" requests */
+static void freq_qos_test_min(struct kunit *test)
+{
+       struct freq_constraints qos;
+       struct freq_qos_request req1, req2;
+       int ret;
+
+       freq_constraints_init(&qos);
+       memset(&req1, 0, sizeof(req1));
+       memset(&req2, 0, sizeof(req2));
+
+       ret = freq_qos_add_request(&qos, &req1, FREQ_QOS_MIN, 1000);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       ret = freq_qos_add_request(&qos, &req2, FREQ_QOS_MIN, 2000);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 2000);
+
+       ret = freq_qos_remove_request(&req2);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 1000);
+
+       ret = freq_qos_remove_request(&req1);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
+                       FREQ_QOS_MIN_DEFAULT_VALUE);
+}
+
+/* Test that requests for MAX_DEFAULT_VALUE have no effect */
+static void freq_qos_test_maxdef(struct kunit *test)
+{
+       struct freq_constraints qos;
+       struct freq_qos_request req1, req2;
+       int ret;
+
+       freq_constraints_init(&qos);
+       memset(&req1, 0, sizeof(req1));
+       memset(&req2, 0, sizeof(req2));
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX),
+                       FREQ_QOS_MAX_DEFAULT_VALUE);
+
+       ret = freq_qos_add_request(&qos, &req1, FREQ_QOS_MAX,
+                       FREQ_QOS_MAX_DEFAULT_VALUE);
+       KUNIT_EXPECT_EQ(test, ret, 0);
+       ret = freq_qos_add_request(&qos, &req2, FREQ_QOS_MAX,
+                       FREQ_QOS_MAX_DEFAULT_VALUE);
+       KUNIT_EXPECT_EQ(test, ret, 0);
+
+       /* Add max 1000 */
+       ret = freq_qos_update_request(&req1, 1000);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 1000);
+
+       /* Add max 2000, no impact */
+       ret = freq_qos_update_request(&req2, 2000);
+       KUNIT_EXPECT_EQ(test, ret, 0);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 1000);
+
+       /* Remove max 1000, new max 2000 */
+       ret = freq_qos_remove_request(&req1);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 2000);
+}
+
+/*
+ * Test that a freq_qos_request can be added again after removal
+ *
+ * This issue was solved by commit 05ff1ba412fd ("PM: QoS: Invalidate frequency
+ * QoS requests after removal")
+ */
+static void freq_qos_test_readd(struct kunit *test)
+{
+       struct freq_constraints qos;
+       struct freq_qos_request req;
+       int ret;
+
+       freq_constraints_init(&qos);
+       memset(&req, 0, sizeof(req));
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
+                       FREQ_QOS_MIN_DEFAULT_VALUE);
+
+       /* Add */
+       ret = freq_qos_add_request(&qos, &req, FREQ_QOS_MIN, 1000);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 1000);
+
+       /* Remove */
+       ret = freq_qos_remove_request(&req);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
+                       FREQ_QOS_MIN_DEFAULT_VALUE);
+
+       /* Add again */
+       ret = freq_qos_add_request(&qos, &req, FREQ_QOS_MIN, 2000);
+       KUNIT_EXPECT_EQ(test, ret, 1);
+       KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 2000);
+}
+
+static struct kunit_case pm_qos_test_cases[] = {
+       KUNIT_CASE(freq_qos_test_min),
+       KUNIT_CASE(freq_qos_test_maxdef),
+       KUNIT_CASE(freq_qos_test_readd),
+       {},
+};
+
+static struct kunit_suite pm_qos_test_module = {
+       .name = "qos-kunit-test",
+       .test_cases = pm_qos_test_cases,
+};
+kunit_test_suite(pm_qos_test_module);
index 350dcaf..8e93167 100644 (file)
@@ -115,10 +115,20 @@ s32 dev_pm_qos_read_value(struct device *dev, enum dev_pm_qos_req_type type)
 
        spin_lock_irqsave(&dev->power.lock, flags);
 
-       if (type == DEV_PM_QOS_RESUME_LATENCY) {
+       switch (type) {
+       case DEV_PM_QOS_RESUME_LATENCY:
                ret = IS_ERR_OR_NULL(qos) ? PM_QOS_RESUME_LATENCY_NO_CONSTRAINT
                        : pm_qos_read_value(&qos->resume_latency);
-       } else {
+               break;
+       case DEV_PM_QOS_MIN_FREQUENCY:
+               ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE
+                       : freq_qos_read_value(&qos->freq, FREQ_QOS_MIN);
+               break;
+       case DEV_PM_QOS_MAX_FREQUENCY:
+               ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE
+                       : freq_qos_read_value(&qos->freq, FREQ_QOS_MAX);
+               break;
+       default:
                WARN_ON(1);
                ret = 0;
        }
@@ -159,6 +169,10 @@ static int apply_constraint(struct dev_pm_qos_request *req,
                        req->dev->power.set_latency_tolerance(req->dev, value);
                }
                break;
+       case DEV_PM_QOS_MIN_FREQUENCY:
+       case DEV_PM_QOS_MAX_FREQUENCY:
+               ret = freq_qos_apply(&req->data.freq, action, value);
+               break;
        case DEV_PM_QOS_FLAGS:
                ret = pm_qos_update_flags(&qos->flags, &req->data.flr,
                                          action, value);
@@ -209,6 +223,8 @@ static int dev_pm_qos_constraints_allocate(struct device *dev)
        c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT;
        c->type = PM_QOS_MIN;
 
+       freq_constraints_init(&qos->freq);
+
        INIT_LIST_HEAD(&qos->flags.list);
 
        spin_lock_irq(&dev->power.lock);
@@ -269,6 +285,20 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
                memset(req, 0, sizeof(*req));
        }
 
+       c = &qos->freq.min_freq;
+       plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
+               apply_constraint(req, PM_QOS_REMOVE_REQ,
+                                PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE);
+               memset(req, 0, sizeof(*req));
+       }
+
+       c = &qos->freq.max_freq;
+       plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
+               apply_constraint(req, PM_QOS_REMOVE_REQ,
+                                PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
+               memset(req, 0, sizeof(*req));
+       }
+
        f = &qos->flags;
        list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {
                apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
@@ -314,11 +344,22 @@ static int __dev_pm_qos_add_request(struct device *dev,
                ret = dev_pm_qos_constraints_allocate(dev);
 
        trace_dev_pm_qos_add_request(dev_name(dev), type, value);
-       if (!ret) {
-               req->dev = dev;
-               req->type = type;
+       if (ret)
+               return ret;
+
+       req->dev = dev;
+       req->type = type;
+       if (req->type == DEV_PM_QOS_MIN_FREQUENCY)
+               ret = freq_qos_add_request(&dev->power.qos->freq,
+                                          &req->data.freq,
+                                          FREQ_QOS_MIN, value);
+       else if (req->type == DEV_PM_QOS_MAX_FREQUENCY)
+               ret = freq_qos_add_request(&dev->power.qos->freq,
+                                          &req->data.freq,
+                                          FREQ_QOS_MAX, value);
+       else
                ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
-       }
+
        return ret;
 }
 
@@ -382,6 +423,10 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
        case DEV_PM_QOS_LATENCY_TOLERANCE:
                curr_value = req->data.pnode.prio;
                break;
+       case DEV_PM_QOS_MIN_FREQUENCY:
+       case DEV_PM_QOS_MAX_FREQUENCY:
+               curr_value = req->data.freq.pnode.prio;
+               break;
        case DEV_PM_QOS_FLAGS:
                curr_value = req->data.flr.flags;
                break;
@@ -507,6 +552,14 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier,
                ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers,
                                                       notifier);
                break;
+       case DEV_PM_QOS_MIN_FREQUENCY:
+               ret = freq_qos_add_notifier(&dev->power.qos->freq,
+                                           FREQ_QOS_MIN, notifier);
+               break;
+       case DEV_PM_QOS_MAX_FREQUENCY:
+               ret = freq_qos_add_notifier(&dev->power.qos->freq,
+                                           FREQ_QOS_MAX, notifier);
+               break;
        default:
                WARN_ON(1);
                ret = -EINVAL;
@@ -546,6 +599,14 @@ int dev_pm_qos_remove_notifier(struct device *dev,
                ret = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers,
                                                         notifier);
                break;
+       case DEV_PM_QOS_MIN_FREQUENCY:
+               ret = freq_qos_remove_notifier(&dev->power.qos->freq,
+                                              FREQ_QOS_MIN, notifier);
+               break;
+       case DEV_PM_QOS_MAX_FREQUENCY:
+               ret = freq_qos_remove_notifier(&dev->power.qos->freq,
+                                              FREQ_QOS_MAX, notifier);
+               break;
        default:
                WARN_ON(1);
                ret = -EINVAL;
index 5817b51..70a9edb 100644 (file)
@@ -248,6 +248,60 @@ void wakeup_source_unregister(struct wakeup_source *ws)
 EXPORT_SYMBOL_GPL(wakeup_source_unregister);
 
 /**
+ * wakeup_sources_read_lock - Lock wakeup source list for read.
+ *
+ * Returns an index of srcu lock for struct wakeup_srcu.
+ * This index must be passed to the matching wakeup_sources_read_unlock().
+ */
+int wakeup_sources_read_lock(void)
+{
+       return srcu_read_lock(&wakeup_srcu);
+}
+EXPORT_SYMBOL_GPL(wakeup_sources_read_lock);
+
+/**
+ * wakeup_sources_read_unlock - Unlock wakeup source list.
+ * @idx: return value from corresponding wakeup_sources_read_lock()
+ */
+void wakeup_sources_read_unlock(int idx)
+{
+       srcu_read_unlock(&wakeup_srcu, idx);
+}
+EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock);
+
+/**
+ * wakeup_sources_walk_start - Begin a walk on wakeup source list
+ *
+ * Returns first object of the list of wakeup sources.
+ *
+ * Note that to be safe, wakeup sources list needs to be locked by calling
+ * wakeup_source_read_lock() for this.
+ */
+struct wakeup_source *wakeup_sources_walk_start(void)
+{
+       struct list_head *ws_head = &wakeup_sources;
+
+       return list_entry_rcu(ws_head->next, struct wakeup_source, entry);
+}
+EXPORT_SYMBOL_GPL(wakeup_sources_walk_start);
+
+/**
+ * wakeup_sources_walk_next - Get next wakeup source from the list
+ * @ws: Previous wakeup source object
+ *
+ * Note that to be safe, wakeup sources list needs to be locked by calling
+ * wakeup_source_read_lock() for this.
+ */
+struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws)
+{
+       struct list_head *ws_head = &wakeup_sources;
+
+       return list_next_or_null_rcu(ws_head, &ws->entry,
+                               struct wakeup_source, entry);
+}
+EXPORT_SYMBOL_GPL(wakeup_sources_walk_next);
+
+/**
  * device_wakeup_attach - Attach a wakeup source object to a device object.
  * @dev: Device to handle.
  * @ws: Wakeup source object to attach to @dev.
index c548a5a..a8730cc 100644 (file)
@@ -297,6 +297,10 @@ static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio)
                unsigned int len = bvec.bv_len;
                int err;
 
+               /* Don't support un-aligned buffer */
+               WARN_ON_ONCE((bvec.bv_offset & (SECTOR_SIZE - 1)) ||
+                               (len & (SECTOR_SIZE - 1)));
+
                err = brd_do_bvec(brd, bvec.bv_page, len, bvec.bv_offset,
                                  bio_op(bio), sector);
                if (err)
@@ -382,7 +386,6 @@ static struct brd_device *brd_alloc(int i)
                goto out_free_dev;
 
        blk_queue_make_request(brd->brd_queue, brd_make_request);
-       blk_queue_max_hw_sectors(brd->brd_queue, 1024);
 
        /* This is so fdisk will align partitions on 4k, because of
         * direct_access API needing 4k alignment, returning a PFN
index 795fda5..ae8d4bc 100644 (file)
@@ -1559,14 +1559,13 @@ static int init_driver_queues(struct nullb *nullb)
 
 static int null_gendisk_register(struct nullb *nullb)
 {
+       sector_t size = ((sector_t)nullb->dev->size * SZ_1M) >> SECTOR_SHIFT;
        struct gendisk *disk;
-       sector_t size;
 
        disk = nullb->disk = alloc_disk_node(1, nullb->dev->home_node);
        if (!disk)
                return -ENOMEM;
-       size = (sector_t)nullb->dev->size * 1024 * 1024ULL;
-       set_capacity(disk, size >> 9);
+       set_capacity(disk, size);
 
        disk->flags |= GENHD_FL_EXT_DEVT | GENHD_FL_SUPPRESS_PARTITION_INFO;
        disk->major             = null_major;
@@ -1576,12 +1575,19 @@ static int null_gendisk_register(struct nullb *nullb)
        disk->queue             = nullb->q;
        strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
 
+#ifdef CONFIG_BLK_DEV_ZONED
        if (nullb->dev->zoned) {
-               int ret = blk_revalidate_disk_zones(disk);
-
-               if (ret != 0)
-                       return ret;
+               if (queue_is_mq(nullb->q)) {
+                       int ret = blk_revalidate_disk_zones(disk);
+                       if (ret)
+                               return ret;
+               } else {
+                       blk_queue_chunk_sectors(nullb->q,
+                                       nullb->dev->zone_size_sects);
+                       nullb->q->nr_zones = blkdev_nr_zones(disk);
+               }
        }
+#endif
 
        add_disk(disk);
        return 0;
@@ -1607,7 +1613,7 @@ static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set)
        return blk_mq_alloc_tag_set(set);
 }
 
-static void null_validate_conf(struct nullb_device *dev)
+static int null_validate_conf(struct nullb_device *dev)
 {
        dev->blocksize = round_down(dev->blocksize, 512);
        dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096);
@@ -1634,6 +1640,14 @@ static void null_validate_conf(struct nullb_device *dev)
        /* can not stop a queue */
        if (dev->queue_mode == NULL_Q_BIO)
                dev->mbps = 0;
+
+       if (dev->zoned &&
+           (!dev->zone_size || !is_power_of_2(dev->zone_size))) {
+               pr_err("zone_size must be power-of-two\n");
+               return -EINVAL;
+       }
+
+       return 0;
 }
 
 #ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION
@@ -1666,7 +1680,9 @@ static int null_add_dev(struct nullb_device *dev)
        struct nullb *nullb;
        int rv;
 
-       null_validate_conf(dev);
+       rv = null_validate_conf(dev);
+       if (rv)
+               return rv;
 
        nullb = kzalloc_node(sizeof(*nullb), GFP_KERNEL, dev->home_node);
        if (!nullb) {
@@ -1731,7 +1747,6 @@ static int null_add_dev(struct nullb_device *dev)
                if (rv)
                        goto out_cleanup_blk_queue;
 
-               blk_queue_chunk_sectors(nullb->q, dev->zone_size_sects);
                nullb->q->limits.zoned = BLK_ZONED_HM;
                blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, nullb->q);
                blk_queue_required_elevator_features(nullb->q,
@@ -1792,11 +1807,6 @@ static int __init null_init(void)
                g_bs = PAGE_SIZE;
        }
 
-       if (!is_power_of_2(g_zone_size)) {
-               pr_err("zone_size must be power-of-two\n");
-               return -EINVAL;
-       }
-
        if (g_home_node != NUMA_NO_NODE && g_home_node >= nr_online_nodes) {
                pr_err("invalid home_node value\n");
                g_home_node = NUMA_NO_NODE;
index 13527a0..2b18456 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/ceph/cls_lock_client.h>
 #include <linux/ceph/striper.h>
 #include <linux/ceph/decode.h>
-#include <linux/parser.h>
+#include <linux/fs_parser.h>
 #include <linux/bsearch.h>
 
 #include <linux/kernel.h>
@@ -377,7 +377,6 @@ struct rbd_client_id {
 
 struct rbd_mapping {
        u64                     size;
-       u64                     features;
 };
 
 /*
@@ -462,8 +461,9 @@ struct rbd_device {
  *   by rbd_dev->lock
  */
 enum rbd_dev_flags {
-       RBD_DEV_FLAG_EXISTS,    /* mapped snapshot has not been deleted */
+       RBD_DEV_FLAG_EXISTS,    /* rbd_dev_device_setup() ran */
        RBD_DEV_FLAG_REMOVING,  /* this mapping is being removed */
+       RBD_DEV_FLAG_READONLY,  /* -o ro or snapshot */
 };
 
 static DEFINE_MUTEX(client_mutex);     /* Serialize client creation */
@@ -514,6 +514,16 @@ static int minor_to_rbd_dev_id(int minor)
        return minor >> RBD_SINGLE_MAJOR_PART_SHIFT;
 }
 
+static bool rbd_is_ro(struct rbd_device *rbd_dev)
+{
+       return test_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags);
+}
+
+static bool rbd_is_snap(struct rbd_device *rbd_dev)
+{
+       return rbd_dev->spec->snap_id != CEPH_NOSNAP;
+}
+
 static bool __rbd_is_lock_owner(struct rbd_device *rbd_dev)
 {
        lockdep_assert_held(&rbd_dev->lock_rwsem);
@@ -633,8 +643,6 @@ static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
                                        u64 snap_id);
 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
                                u8 *order, u64 *snap_size);
-static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
-               u64 *snap_features);
 static int rbd_dev_v2_get_flags(struct rbd_device *rbd_dev);
 
 static void rbd_obj_handle_request(struct rbd_obj_request *obj_req, int result);
@@ -695,9 +703,16 @@ static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg)
        if (get_user(ro, (int __user *)arg))
                return -EFAULT;
 
-       /* Snapshots can't be marked read-write */
-       if (rbd_dev->spec->snap_id != CEPH_NOSNAP && !ro)
-               return -EROFS;
+       /*
+        * Both images mapped read-only and snapshots can't be marked
+        * read-write.
+        */
+       if (!ro) {
+               if (rbd_is_ro(rbd_dev))
+                       return -EROFS;
+
+               rbd_assert(!rbd_is_snap(rbd_dev));
+       }
 
        /* Let blkdev_roset() handle it */
        return -ENOTTY;
@@ -823,34 +838,34 @@ enum {
        Opt_queue_depth,
        Opt_alloc_size,
        Opt_lock_timeout,
-       Opt_last_int,
        /* int args above */
        Opt_pool_ns,
-       Opt_last_string,
        /* string args above */
        Opt_read_only,
        Opt_read_write,
        Opt_lock_on_read,
        Opt_exclusive,
        Opt_notrim,
-       Opt_err
 };
 
-static match_table_t rbd_opts_tokens = {
-       {Opt_queue_depth, "queue_depth=%d"},
-       {Opt_alloc_size, "alloc_size=%d"},
-       {Opt_lock_timeout, "lock_timeout=%d"},
-       /* int args above */
-       {Opt_pool_ns, "_pool_ns=%s"},
-       /* string args above */
-       {Opt_read_only, "read_only"},
-       {Opt_read_only, "ro"},          /* Alternate spelling */
-       {Opt_read_write, "read_write"},
-       {Opt_read_write, "rw"},         /* Alternate spelling */
-       {Opt_lock_on_read, "lock_on_read"},
-       {Opt_exclusive, "exclusive"},
-       {Opt_notrim, "notrim"},
-       {Opt_err, NULL}
+static const struct fs_parameter_spec rbd_param_specs[] = {
+       fsparam_u32     ("alloc_size",                  Opt_alloc_size),
+       fsparam_flag    ("exclusive",                   Opt_exclusive),
+       fsparam_flag    ("lock_on_read",                Opt_lock_on_read),
+       fsparam_u32     ("lock_timeout",                Opt_lock_timeout),
+       fsparam_flag    ("notrim",                      Opt_notrim),
+       fsparam_string  ("_pool_ns",                    Opt_pool_ns),
+       fsparam_u32     ("queue_depth",                 Opt_queue_depth),
+       fsparam_flag    ("read_only",                   Opt_read_only),
+       fsparam_flag    ("read_write",                  Opt_read_write),
+       fsparam_flag    ("ro",                          Opt_read_only),
+       fsparam_flag    ("rw",                          Opt_read_write),
+       {}
+};
+
+static const struct fs_parameter_description rbd_parameters = {
+       .name           = "rbd",
+       .specs          = rbd_param_specs,
 };
 
 struct rbd_options {
@@ -871,87 +886,12 @@ struct rbd_options {
 #define RBD_EXCLUSIVE_DEFAULT  false
 #define RBD_TRIM_DEFAULT       true
 
-struct parse_rbd_opts_ctx {
+struct rbd_parse_opts_ctx {
        struct rbd_spec         *spec;
+       struct ceph_options     *copts;
        struct rbd_options      *opts;
 };
 
-static int parse_rbd_opts_token(char *c, void *private)
-{
-       struct parse_rbd_opts_ctx *pctx = private;
-       substring_t argstr[MAX_OPT_ARGS];
-       int token, intval, ret;
-
-       token = match_token(c, rbd_opts_tokens, argstr);
-       if (token < Opt_last_int) {
-               ret = match_int(&argstr[0], &intval);
-               if (ret < 0) {
-                       pr_err("bad option arg (not int) at '%s'\n", c);
-                       return ret;
-               }
-               dout("got int token %d val %d\n", token, intval);
-       } else if (token > Opt_last_int && token < Opt_last_string) {
-               dout("got string token %d val %s\n", token, argstr[0].from);
-       } else {
-               dout("got token %d\n", token);
-       }
-
-       switch (token) {
-       case Opt_queue_depth:
-               if (intval < 1) {
-                       pr_err("queue_depth out of range\n");
-                       return -EINVAL;
-               }
-               pctx->opts->queue_depth = intval;
-               break;
-       case Opt_alloc_size:
-               if (intval < SECTOR_SIZE) {
-                       pr_err("alloc_size out of range\n");
-                       return -EINVAL;
-               }
-               if (!is_power_of_2(intval)) {
-                       pr_err("alloc_size must be a power of 2\n");
-                       return -EINVAL;
-               }
-               pctx->opts->alloc_size = intval;
-               break;
-       case Opt_lock_timeout:
-               /* 0 is "wait forever" (i.e. infinite timeout) */
-               if (intval < 0 || intval > INT_MAX / 1000) {
-                       pr_err("lock_timeout out of range\n");
-                       return -EINVAL;
-               }
-               pctx->opts->lock_timeout = msecs_to_jiffies(intval * 1000);
-               break;
-       case Opt_pool_ns:
-               kfree(pctx->spec->pool_ns);
-               pctx->spec->pool_ns = match_strdup(argstr);
-               if (!pctx->spec->pool_ns)
-                       return -ENOMEM;
-               break;
-       case Opt_read_only:
-               pctx->opts->read_only = true;
-               break;
-       case Opt_read_write:
-               pctx->opts->read_only = false;
-               break;
-       case Opt_lock_on_read:
-               pctx->opts->lock_on_read = true;
-               break;
-       case Opt_exclusive:
-               pctx->opts->exclusive = true;
-               break;
-       case Opt_notrim:
-               pctx->opts->trim = false;
-               break;
-       default:
-               /* libceph prints "bad option" msg */
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 static char* obj_op_name(enum obj_operation_type op_type)
 {
        switch (op_type) {
@@ -1302,51 +1242,23 @@ static int rbd_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
        return 0;
 }
 
-static int rbd_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
-                       u64 *snap_features)
-{
-       rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
-       if (snap_id == CEPH_NOSNAP) {
-               *snap_features = rbd_dev->header.features;
-       } else if (rbd_dev->image_format == 1) {
-               *snap_features = 0;     /* No features for format 1 */
-       } else {
-               u64 features = 0;
-               int ret;
-
-               ret = _rbd_dev_v2_snap_features(rbd_dev, snap_id, &features);
-               if (ret)
-                       return ret;
-
-               *snap_features = features;
-       }
-       return 0;
-}
-
 static int rbd_dev_mapping_set(struct rbd_device *rbd_dev)
 {
        u64 snap_id = rbd_dev->spec->snap_id;
        u64 size = 0;
-       u64 features = 0;
        int ret;
 
        ret = rbd_snap_size(rbd_dev, snap_id, &size);
        if (ret)
                return ret;
-       ret = rbd_snap_features(rbd_dev, snap_id, &features);
-       if (ret)
-               return ret;
 
        rbd_dev->mapping.size = size;
-       rbd_dev->mapping.features = features;
-
        return 0;
 }
 
 static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev)
 {
        rbd_dev->mapping.size = 0;
-       rbd_dev->mapping.features = 0;
 }
 
 static void zero_bvec(struct bio_vec *bv)
@@ -1832,6 +1744,17 @@ static u8 rbd_object_map_get(struct rbd_device *rbd_dev, u64 objno)
 
 static bool use_object_map(struct rbd_device *rbd_dev)
 {
+       /*
+        * An image mapped read-only can't use the object map -- it isn't
+        * loaded because the header lock isn't acquired.  Someone else can
+        * write to the image and update the object map behind our back.
+        *
+        * A snapshot can't be written to, so using the object map is always
+        * safe.
+        */
+       if (!rbd_is_snap(rbd_dev) && rbd_is_ro(rbd_dev))
+               return false;
+
        return ((rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) &&
                !(rbd_dev->object_map_flags & RBD_FLAG_OBJECT_MAP_INVALID));
 }
@@ -3555,7 +3478,7 @@ static bool need_exclusive_lock(struct rbd_img_request *img_req)
        if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK))
                return false;
 
-       if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
+       if (rbd_is_ro(rbd_dev))
                return false;
 
        rbd_assert(!test_bit(IMG_REQ_CHILD, &img_req->flags));
@@ -4230,7 +4153,7 @@ again:
                 * lock owner acked, but resend if we don't see them
                 * release the lock
                 */
-               dout("%s rbd_dev %p requeueing lock_dwork\n", __func__,
+               dout("%s rbd_dev %p requeuing lock_dwork\n", __func__,
                     rbd_dev);
                mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork,
                    msecs_to_jiffies(2 * RBD_NOTIFY_TIMEOUT * MSEC_PER_SEC));
@@ -4826,24 +4749,14 @@ static void rbd_queue_workfn(struct work_struct *work)
                goto err_rq;
        }
 
-       if (op_type != OBJ_OP_READ && rbd_dev->spec->snap_id != CEPH_NOSNAP) {
-               rbd_warn(rbd_dev, "%s on read-only snapshot",
-                        obj_op_name(op_type));
-               result = -EIO;
-               goto err;
-       }
-
-       /*
-        * Quit early if the mapped snapshot no longer exists.  It's
-        * still possible the snapshot will have disappeared by the
-        * time our request arrives at the osd, but there's no sense in
-        * sending it if we already know.
-        */
-       if (!test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags)) {
-               dout("request for non-existent snapshot");
-               rbd_assert(rbd_dev->spec->snap_id != CEPH_NOSNAP);
-               result = -ENXIO;
-               goto err_rq;
+       if (op_type != OBJ_OP_READ) {
+               if (rbd_is_ro(rbd_dev)) {
+                       rbd_warn(rbd_dev, "%s on read-only mapping",
+                                obj_op_name(op_type));
+                       result = -EIO;
+                       goto err;
+               }
+               rbd_assert(!rbd_is_snap(rbd_dev));
        }
 
        if (offset && length > U64_MAX - offset + 1) {
@@ -5025,25 +4938,6 @@ out:
        return ret;
 }
 
-/*
- * Clear the rbd device's EXISTS flag if the snapshot it's mapped to
- * has disappeared from the (just updated) snapshot context.
- */
-static void rbd_exists_validate(struct rbd_device *rbd_dev)
-{
-       u64 snap_id;
-
-       if (!test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags))
-               return;
-
-       snap_id = rbd_dev->spec->snap_id;
-       if (snap_id == CEPH_NOSNAP)
-               return;
-
-       if (rbd_dev_snap_index(rbd_dev, snap_id) == BAD_SNAP_INDEX)
-               clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
-}
-
 static void rbd_dev_update_size(struct rbd_device *rbd_dev)
 {
        sector_t size;
@@ -5084,12 +4978,8 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev)
                        goto out;
        }
 
-       if (rbd_dev->spec->snap_id == CEPH_NOSNAP) {
-               rbd_dev->mapping.size = rbd_dev->header.image_size;
-       } else {
-               /* validate mapped snapshot's EXISTS flag */
-               rbd_exists_validate(rbd_dev);
-       }
+       rbd_assert(!rbd_is_snap(rbd_dev));
+       rbd_dev->mapping.size = rbd_dev->header.image_size;
 
 out:
        up_write(&rbd_dev->header_rwsem);
@@ -5211,17 +5101,12 @@ static ssize_t rbd_size_show(struct device *dev,
                (unsigned long long)rbd_dev->mapping.size);
 }
 
-/*
- * Note this shows the features for whatever's mapped, which is not
- * necessarily the base image.
- */
 static ssize_t rbd_features_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
        struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
-       return sprintf(buf, "0x%016llx\n",
-                       (unsigned long long)rbd_dev->mapping.features);
+       return sprintf(buf, "0x%016llx\n", rbd_dev->header.features);
 }
 
 static ssize_t rbd_major_show(struct device *dev,
@@ -5709,9 +5594,12 @@ out:
 }
 
 static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
-               u64 *snap_features)
+                                    bool read_only, u64 *snap_features)
 {
-       __le64 snapid = cpu_to_le64(snap_id);
+       struct {
+               __le64 snap_id;
+               u8 read_only;
+       } features_in;
        struct {
                __le64 features;
                __le64 incompat;
@@ -5719,9 +5607,12 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
        u64 unsup;
        int ret;
 
+       features_in.snap_id = cpu_to_le64(snap_id);
+       features_in.read_only = read_only;
+
        ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
                                  &rbd_dev->header_oloc, "get_features",
-                                 &snapid, sizeof(snapid),
+                                 &features_in, sizeof(features_in),
                                  &features_buf, sizeof(features_buf));
        dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
        if (ret < 0)
@@ -5749,7 +5640,8 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
 static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
 {
        return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
-                                               &rbd_dev->header.features);
+                                        rbd_is_ro(rbd_dev),
+                                        &rbd_dev->header.features);
 }
 
 /*
@@ -6456,6 +6348,122 @@ static inline char *dup_token(const char **buf, size_t *lenp)
        return dup;
 }
 
+static int rbd_parse_param(struct fs_parameter *param,
+                           struct rbd_parse_opts_ctx *pctx)
+{
+       struct rbd_options *opt = pctx->opts;
+       struct fs_parse_result result;
+       int token, ret;
+
+       ret = ceph_parse_param(param, pctx->copts, NULL);
+       if (ret != -ENOPARAM)
+               return ret;
+
+       token = fs_parse(NULL, &rbd_parameters, param, &result);
+       dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
+       if (token < 0) {
+               if (token == -ENOPARAM) {
+                       return invalf(NULL, "rbd: Unknown parameter '%s'",
+                                     param->key);
+               }
+               return token;
+       }
+
+       switch (token) {
+       case Opt_queue_depth:
+               if (result.uint_32 < 1)
+                       goto out_of_range;
+               opt->queue_depth = result.uint_32;
+               break;
+       case Opt_alloc_size:
+               if (result.uint_32 < SECTOR_SIZE)
+                       goto out_of_range;
+               if (!is_power_of_2(result.uint_32)) {
+                       return invalf(NULL, "rbd: alloc_size must be a power of 2");
+               }
+               opt->alloc_size = result.uint_32;
+               break;
+       case Opt_lock_timeout:
+               /* 0 is "wait forever" (i.e. infinite timeout) */
+               if (result.uint_32 > INT_MAX / 1000)
+                       goto out_of_range;
+               opt->lock_timeout = msecs_to_jiffies(result.uint_32 * 1000);
+               break;
+       case Opt_pool_ns:
+               kfree(pctx->spec->pool_ns);
+               pctx->spec->pool_ns = param->string;
+               param->string = NULL;
+               break;
+       case Opt_read_only:
+               opt->read_only = true;
+               break;
+       case Opt_read_write:
+               opt->read_only = false;
+               break;
+       case Opt_lock_on_read:
+               opt->lock_on_read = true;
+               break;
+       case Opt_exclusive:
+               opt->exclusive = true;
+               break;
+       case Opt_notrim:
+               opt->trim = false;
+               break;
+       default:
+               BUG();
+       }
+
+       return 0;
+
+out_of_range:
+       return invalf(NULL, "rbd: %s out of range", param->key);
+}
+
+/*
+ * This duplicates most of generic_parse_monolithic(), untying it from
+ * fs_context and skipping standard superblock and security options.
+ */
+static int rbd_parse_options(char *options, struct rbd_parse_opts_ctx *pctx)
+{
+       char *key;
+       int ret = 0;
+
+       dout("%s '%s'\n", __func__, options);
+       while ((key = strsep(&options, ",")) != NULL) {
+               if (*key) {
+                       struct fs_parameter param = {
+                               .key    = key,
+                               .type   = fs_value_is_string,
+                       };
+                       char *value = strchr(key, '=');
+                       size_t v_len = 0;
+
+                       if (value) {
+                               if (value == key)
+                                       continue;
+                               *value++ = 0;
+                               v_len = strlen(value);
+                       }
+
+
+                       if (v_len > 0) {
+                               param.string = kmemdup_nul(value, v_len,
+                                                          GFP_KERNEL);
+                               if (!param.string)
+                                       return -ENOMEM;
+                       }
+                       param.size = v_len;
+
+                       ret = rbd_parse_param(&param, pctx);
+                       kfree(param.string);
+                       if (ret)
+                               break;
+               }
+       }
+
+       return ret;
+}
+
 /*
  * Parse the options provided for an "rbd add" (i.e., rbd image
  * mapping) request.  These arrive via a write to /sys/bus/rbd/add,
@@ -6507,8 +6515,7 @@ static int rbd_add_parse_args(const char *buf,
        const char *mon_addrs;
        char *snap_name;
        size_t mon_addrs_size;
-       struct parse_rbd_opts_ctx pctx = { 0 };
-       struct ceph_options *copts;
+       struct rbd_parse_opts_ctx pctx = { 0 };
        int ret;
 
        /* The first four tokens are required */
@@ -6519,7 +6526,7 @@ static int rbd_add_parse_args(const char *buf,
                return -EINVAL;
        }
        mon_addrs = buf;
-       mon_addrs_size = len + 1;
+       mon_addrs_size = len;
        buf += len;
 
        ret = -EINVAL;
@@ -6569,6 +6576,10 @@ static int rbd_add_parse_args(const char *buf,
        *(snap_name + len) = '\0';
        pctx.spec->snap_name = snap_name;
 
+       pctx.copts = ceph_alloc_options();
+       if (!pctx.copts)
+               goto out_mem;
+
        /* Initialize all rbd options to the defaults */
 
        pctx.opts = kzalloc(sizeof(*pctx.opts), GFP_KERNEL);
@@ -6583,27 +6594,27 @@ static int rbd_add_parse_args(const char *buf,
        pctx.opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
        pctx.opts->trim = RBD_TRIM_DEFAULT;
 
-       copts = ceph_parse_options(options, mon_addrs,
-                                  mon_addrs + mon_addrs_size - 1,
-                                  parse_rbd_opts_token, &pctx);
-       if (IS_ERR(copts)) {
-               ret = PTR_ERR(copts);
+       ret = ceph_parse_mon_ips(mon_addrs, mon_addrs_size, pctx.copts, NULL);
+       if (ret)
+               goto out_err;
+
+       ret = rbd_parse_options(options, &pctx);
+       if (ret)
                goto out_err;
-       }
-       kfree(options);
 
-       *ceph_opts = copts;
+       *ceph_opts = pctx.copts;
        *opts = pctx.opts;
        *rbd_spec = pctx.spec;
-
+       kfree(options);
        return 0;
+
 out_mem:
        ret = -ENOMEM;
 out_err:
        kfree(pctx.opts);
+       ceph_destroy_options(pctx.copts);
        rbd_spec_put(pctx.spec);
        kfree(options);
-
        return ret;
 }
 
@@ -6632,7 +6643,7 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
                return -EINVAL;
        }
 
-       if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
+       if (rbd_is_ro(rbd_dev))
                return 0;
 
        rbd_assert(!rbd_is_lock_owner(rbd_dev));
@@ -6838,6 +6849,8 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
        __rbd_get_client(rbd_dev->rbd_client);
        rbd_spec_get(rbd_dev->parent_spec);
 
+       __set_bit(RBD_DEV_FLAG_READONLY, &parent->flags);
+
        ret = rbd_dev_image_probe(parent, depth);
        if (ret < 0)
                goto out_err;
@@ -6889,7 +6902,7 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
                goto err_out_blkdev;
 
        set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
-       set_disk_ro(rbd_dev->disk, rbd_dev->opts->read_only);
+       set_disk_ro(rbd_dev->disk, rbd_is_ro(rbd_dev));
 
        ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id);
        if (ret)
@@ -6927,6 +6940,24 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev)
        return ret;
 }
 
+static void rbd_print_dne(struct rbd_device *rbd_dev, bool is_snap)
+{
+       if (!is_snap) {
+               pr_info("image %s/%s%s%s does not exist\n",
+                       rbd_dev->spec->pool_name,
+                       rbd_dev->spec->pool_ns ?: "",
+                       rbd_dev->spec->pool_ns ? "/" : "",
+                       rbd_dev->spec->image_name);
+       } else {
+               pr_info("snap %s/%s%s%s@%s does not exist\n",
+                       rbd_dev->spec->pool_name,
+                       rbd_dev->spec->pool_ns ?: "",
+                       rbd_dev->spec->pool_ns ? "/" : "",
+                       rbd_dev->spec->image_name,
+                       rbd_dev->spec->snap_name);
+       }
+}
+
 static void rbd_dev_image_release(struct rbd_device *rbd_dev)
 {
        rbd_dev_unprobe(rbd_dev);
@@ -6945,6 +6976,7 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
  */
 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
 {
+       bool need_watch = !rbd_is_ro(rbd_dev);
        int ret;
 
        /*
@@ -6961,22 +6993,21 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
        if (ret)
                goto err_out_format;
 
-       if (!depth) {
+       if (need_watch) {
                ret = rbd_register_watch(rbd_dev);
                if (ret) {
                        if (ret == -ENOENT)
-                               pr_info("image %s/%s%s%s does not exist\n",
-                                       rbd_dev->spec->pool_name,
-                                       rbd_dev->spec->pool_ns ?: "",
-                                       rbd_dev->spec->pool_ns ? "/" : "",
-                                       rbd_dev->spec->image_name);
+                               rbd_print_dne(rbd_dev, false);
                        goto err_out_format;
                }
        }
 
        ret = rbd_dev_header_info(rbd_dev);
-       if (ret)
+       if (ret) {
+               if (ret == -ENOENT && !need_watch)
+                       rbd_print_dne(rbd_dev, false);
                goto err_out_watch;
+       }
 
        /*
         * If this image is the one being mapped, we have pool name and
@@ -6990,12 +7021,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
                ret = rbd_spec_fill_names(rbd_dev);
        if (ret) {
                if (ret == -ENOENT)
-                       pr_info("snap %s/%s%s%s@%s does not exist\n",
-                               rbd_dev->spec->pool_name,
-                               rbd_dev->spec->pool_ns ?: "",
-                               rbd_dev->spec->pool_ns ? "/" : "",
-                               rbd_dev->spec->image_name,
-                               rbd_dev->spec->snap_name);
+                       rbd_print_dne(rbd_dev, true);
                goto err_out_probe;
        }
 
@@ -7003,7 +7029,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
        if (ret)
                goto err_out_probe;
 
-       if (rbd_dev->spec->snap_id != CEPH_NOSNAP &&
+       if (rbd_is_snap(rbd_dev) &&
            (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) {
                ret = rbd_object_map_load(rbd_dev);
                if (ret)
@@ -7027,7 +7053,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
 err_out_probe:
        rbd_dev_unprobe(rbd_dev);
 err_out_watch:
-       if (!depth)
+       if (need_watch)
                rbd_unregister_watch(rbd_dev);
 err_out_format:
        rbd_dev->image_format = 0;
@@ -7079,6 +7105,11 @@ 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 */
 
+       /* if we are mapping a snapshot it will be a read-only mapping */
+       if (rbd_dev->opts->read_only ||
+           strcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME))
+               __set_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags);
+
        rbd_dev->config_info = kstrdup(buf, GFP_KERNEL);
        if (!rbd_dev->config_info) {
                rc = -ENOMEM;
@@ -7092,10 +7123,6 @@ static ssize_t do_rbd_add(struct bus_type *bus,
                goto err_out_rbd_dev;
        }
 
-       /* If we are mapping a snapshot it must be marked read-only */
-       if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
-               rbd_dev->opts->read_only = true;
-
        if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) {
                rbd_warn(rbd_dev, "alloc_size adjusted to %u",
                         rbd_dev->layout.object_size);
index fd1e19f..716b99a 100644 (file)
@@ -936,6 +936,8 @@ next:
 out_of_memory:
        pr_alert("%s: out of memory\n", __func__);
        put_free_pages(ring, pages_to_gnt, segs_to_map);
+       for (i = last_map; i < num; i++)
+               pages[i]->handle = BLKBACK_INVALID_HANDLE;
        return -ENOMEM;
 }
 
@@ -1504,5 +1506,13 @@ static int __init xen_blkif_init(void)
 
 module_init(xen_blkif_init);
 
+static void __exit xen_blkif_fini(void)
+{
+       xen_blkif_xenbus_fini();
+       xen_blkif_interface_fini();
+}
+
+module_exit(xen_blkif_fini);
+
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_ALIAS("xen-backend:vbd");
index 1d3002d..49132b0 100644 (file)
@@ -375,9 +375,12 @@ struct phys_req {
        struct block_device     *bdev;
        blkif_sector_t          sector_number;
 };
+
 int xen_blkif_interface_init(void);
+void xen_blkif_interface_fini(void);
 
 int xen_blkif_xenbus_init(void);
+void xen_blkif_xenbus_fini(void);
 
 irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
 int xen_blkif_schedule(void *arg);
index b90dbcd..d6a6adf 100644 (file)
@@ -171,6 +171,15 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
        blkif->domid = domid;
        atomic_set(&blkif->refcnt, 1);
        init_completion(&blkif->drain_complete);
+
+       /*
+        * Because freeing back to the cache may be deferred, it is not
+        * safe to unload the module (and hence destroy the cache) until
+        * this has completed. To prevent premature unloading, take an
+        * extra module reference here and release only when the object
+        * has been freed back to the cache.
+        */
+       __module_get(THIS_MODULE);
        INIT_WORK(&blkif->free_work, xen_blkif_deferred_free);
 
        return blkif;
@@ -320,6 +329,7 @@ static void xen_blkif_free(struct xen_blkif *blkif)
 
        /* Make sure everything is drained before shutting down */
        kmem_cache_free(xen_blkif_cachep, blkif);
+       module_put(THIS_MODULE);
 }
 
 int __init xen_blkif_interface_init(void)
@@ -333,6 +343,12 @@ int __init xen_blkif_interface_init(void)
        return 0;
 }
 
+void xen_blkif_interface_fini(void)
+{
+       kmem_cache_destroy(xen_blkif_cachep);
+       xen_blkif_cachep = NULL;
+}
+
 /*
  *  sysfs interface for VBD I/O requests
  */
@@ -1122,3 +1138,8 @@ int xen_blkif_xenbus_init(void)
 {
        return xenbus_register_backend(&xen_blkbk_driver);
 }
+
+void xen_blkif_xenbus_fini(void)
+{
+       xenbus_unregister_driver(&xen_blkbk_driver);
+}
index 97ab5ad..50200d1 100644 (file)
@@ -41,8 +41,9 @@ config MOXTET
 
 config HISILICON_LPC
        bool "Support for ISA I/O space on HiSilicon Hip06/7"
-       depends on ARM64 && (ARCH_HISI || COMPILE_TEST)
-       select INDIRECT_PIO
+       depends on (ARM64 && ARCH_HISI) || (COMPILE_TEST && !ALPHA && !HEXAGON && !PARISC && !C6X)
+       depends on HAS_IOMEM
+       select INDIRECT_PIO if ARM64
        help
          Driver to enable I/O access to devices attached to the Low Pin
          Count bus on the HiSilicon Hip06/7 SoC.
index 20c9571..8101df9 100644 (file)
@@ -74,7 +74,7 @@ struct hisi_lpc_dev {
 /* About 10us. This is specific for single IO operations, such as inb */
 #define LPC_PEROP_WAITCNT      100
 
-static int wait_lpc_idle(unsigned char *mbase, unsigned int waitcnt)
+static int wait_lpc_idle(void __iomem *mbase, unsigned int waitcnt)
 {
        u32 status;
 
@@ -209,7 +209,7 @@ static u32 hisi_lpc_comm_in(void *hostdata, unsigned long pio, size_t dwidth)
        struct hisi_lpc_dev *lpcdev = hostdata;
        struct lpc_cycle_para iopara;
        unsigned long addr;
-       u32 rd_data = 0;
+       __le32 rd_data = 0;
        int ret;
 
        if (!lpcdev || !dwidth || dwidth > LPC_MAX_DWIDTH)
@@ -244,13 +244,12 @@ static void hisi_lpc_comm_out(void *hostdata, unsigned long pio,
        struct lpc_cycle_para iopara;
        const unsigned char *buf;
        unsigned long addr;
+       __le32 _val = cpu_to_le32(val);
 
        if (!lpcdev || !dwidth || dwidth > LPC_MAX_DWIDTH)
                return;
 
-       val = cpu_to_le32(val);
-
-       buf = (const unsigned char *)&val;
+       buf = (const unsigned char *)&_val;
        addr = hisi_lpc_pio_to_addr(lpcdev, pio);
 
        iopara.opflags = FG_INCRADDR_LPC;
index 2b6670d..f4d1597 100644 (file)
@@ -917,6 +917,9 @@ set_midle:
                return -EINVAL;
        }
 
+       if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY)
+               best_mode = SYSC_IDLE_NO;
+
        reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift);
        reg |= best_mode << regbits->midle_shift;
        sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
@@ -978,6 +981,10 @@ static int sysc_disable_module(struct device *dev)
                return ret;
        }
 
+       if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_MSTANDBY) ||
+           ddata->cfg.quirks & (SYSC_QUIRK_FORCE_MSTANDBY))
+               best_mode = SYSC_IDLE_FORCE;
+
        reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift);
        reg |= best_mode << regbits->midle_shift;
        sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
@@ -1037,8 +1044,6 @@ static int __maybe_unused sysc_runtime_resume_legacy(struct device *dev,
        struct ti_sysc_platform_data *pdata;
        int error;
 
-       reset_control_deassert(ddata->rsts);
-
        pdata = dev_get_platdata(ddata->dev);
        if (!pdata)
                return 0;
@@ -1051,6 +1056,8 @@ static int __maybe_unused sysc_runtime_resume_legacy(struct device *dev,
                dev_err(dev, "%s: could not enable: %i\n",
                        __func__, error);
 
+       reset_control_deassert(ddata->rsts);
+
        return 0;
 }
 
@@ -1104,8 +1111,6 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 
        sysc_clkdm_deny_idle(ddata);
 
-       reset_control_deassert(ddata->rsts);
-
        if (sysc_opt_clks_needed(ddata)) {
                error = sysc_enable_opt_clocks(ddata);
                if (error)
@@ -1116,6 +1121,8 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
        if (error)
                goto err_opt_clocks;
 
+       reset_control_deassert(ddata->rsts);
+
        if (ddata->legacy_mode) {
                error = sysc_runtime_resume_legacy(dev, ddata);
                if (error)
@@ -1236,6 +1243,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
                   SYSC_QUIRK_SWSUP_SIDLE),
 
        /* Quirks that need to be set based on detected module */
+       SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff,
+                  SYSC_MODULE_QUIRK_AESS),
        SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
                   SYSC_MODULE_QUIRK_HDQ1W),
        SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff,
@@ -1251,6 +1260,10 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("gpu", 0x50000000, 0x14, -1, -1, 0x00010201, 0xffffffff, 0),
        SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -1, 0x40000000 , 0xffffffff,
                   SYSC_MODULE_QUIRK_SGX),
+       SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
+                  0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
+       SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -1, 0x4ea2080d, 0xffffffff,
+                  SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
        SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
                   SYSC_MODULE_QUIRK_WDT),
        /* Watchdog on am3 and am4 */
@@ -1260,7 +1273,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
 #ifdef DEBUG
        SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0),
        SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0),
-       SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff, 0),
        SYSC_QUIRK("cm", 0, 0, -1, -1, 0x40000301, 0xffffffff, 0),
        SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, 0),
        SYSC_QUIRK("cpgmac", 0, 0x1200, 0x1208, 0x1204, 0x4edb1902,
@@ -1309,8 +1321,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000008, 0xffffffff, 0),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0),
-       SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
-                  0xffffffff, 0),
        SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0),
 #endif
 };
@@ -1394,6 +1404,14 @@ static void sysc_clk_enable_quirk_hdq1w(struct sysc *ddata)
        sysc_write(ddata, offset, val);
 }
 
+/* AESS (Audio Engine SubSystem) needs autogating set after enable */
+static void sysc_module_enable_quirk_aess(struct sysc *ddata)
+{
+       int offset = 0x7c;      /* AESS_AUTO_GATING_ENABLE */
+
+       sysc_write(ddata, offset, 1);
+}
+
 /* I2C needs extra enable bit toggling for reset */
 static void sysc_clk_quirk_i2c(struct sysc *ddata, bool enable)
 {
@@ -1476,6 +1494,9 @@ static void sysc_init_module_quirks(struct sysc *ddata)
                return;
        }
 
+       if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_AESS)
+               ddata->module_enable_quirk = sysc_module_enable_quirk_aess;
+
        if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_SGX)
                ddata->module_enable_quirk = sysc_module_enable_quirk_sgx;
 
@@ -1532,37 +1553,6 @@ static int sysc_legacy_init(struct sysc *ddata)
        return error;
 }
 
-/**
- * sysc_rstctrl_reset_deassert - deassert rstctrl reset
- * @ddata: device driver data
- * @reset: reset before deassert
- *
- * A module can have both OCP softreset control and external rstctrl.
- * If more complicated rstctrl resets are needed, please handle these
- * directly from the child device driver and map only the module reset
- * for the parent interconnect target module device.
- *
- * Automatic reset of the module on init can be skipped with the
- * "ti,no-reset-on-init" device tree property.
- */
-static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset)
-{
-       int error;
-
-       if (!ddata->rsts)
-               return 0;
-
-       if (reset) {
-               error = reset_control_assert(ddata->rsts);
-               if (error)
-                       return error;
-       }
-
-       reset_control_deassert(ddata->rsts);
-
-       return 0;
-}
-
 /*
  * Note that the caller must ensure the interconnect target module is enabled
  * before calling reset. Otherwise reset will not complete.
@@ -1594,6 +1584,10 @@ static int sysc_reset(struct sysc *ddata)
        sysc_val |= sysc_mask;
        sysc_write(ddata, sysc_offset, sysc_val);
 
+       if (ddata->cfg.srst_udelay)
+               usleep_range(ddata->cfg.srst_udelay,
+                            ddata->cfg.srst_udelay * 2);
+
        if (ddata->clk_enable_quirk)
                ddata->clk_enable_quirk(ddata);
 
@@ -1625,15 +1619,6 @@ static int sysc_reset(struct sysc *ddata)
 static int sysc_init_module(struct sysc *ddata)
 {
        int error = 0;
-       bool manage_clocks = true;
-
-       error = sysc_rstctrl_reset_deassert(ddata, false);
-       if (error)
-               return error;
-
-       if (ddata->cfg.quirks &
-           (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))
-               manage_clocks = false;
 
        error = sysc_clockdomain_init(ddata);
        if (error)
@@ -1654,7 +1639,7 @@ static int sysc_init_module(struct sysc *ddata)
                goto err_opt_clocks;
 
        if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
-               error = sysc_rstctrl_reset_deassert(ddata, true);
+               error = reset_control_deassert(ddata->rsts);
                if (error)
                        goto err_main_clocks;
        }
@@ -1666,28 +1651,32 @@ static int sysc_init_module(struct sysc *ddata)
        if (ddata->legacy_mode) {
                error = sysc_legacy_init(ddata);
                if (error)
-                       goto err_main_clocks;
+                       goto err_reset;
        }
 
        if (!ddata->legacy_mode) {
                error = sysc_enable_module(ddata->dev);
                if (error)
-                       goto err_main_clocks;
+                       goto err_reset;
        }
 
        error = sysc_reset(ddata);
        if (error)
                dev_err(ddata->dev, "Reset failed with %d\n", error);
 
-       if (!ddata->legacy_mode && manage_clocks)
+       if (error && !ddata->legacy_mode)
                sysc_disable_module(ddata->dev);
 
+err_reset:
+       if (error && !(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
+               reset_control_assert(ddata->rsts);
+
 err_main_clocks:
-       if (manage_clocks)
+       if (error)
                sysc_disable_main_clocks(ddata);
 err_opt_clocks:
        /* No re-enable of clockdomain autoidle to prevent module autoidle */
-       if (manage_clocks) {
+       if (error) {
                sysc_disable_opt_clocks(ddata);
                sysc_clkdm_allow_idle(ddata);
        }
@@ -1794,9 +1783,8 @@ static int sysc_child_add_named_clock(struct sysc *ddata,
 
        clk = clk_get(child, name);
        if (!IS_ERR(clk)) {
-               clk_put(clk);
-
-               return -EEXIST;
+               error = -EEXIST;
+               goto put_clk;
        }
 
        clk = clk_get(ddata->dev, name);
@@ -1806,7 +1794,7 @@ static int sysc_child_add_named_clock(struct sysc *ddata,
        l = clkdev_create(clk, name, dev_name(child));
        if (!l)
                error = -ENOMEM;
-
+put_clk:
        clk_put(clk);
 
        return error;
@@ -2460,10 +2448,17 @@ static int sysc_probe(struct platform_device *pdev)
                goto unprepare;
        }
 
-       /* Balance reset counts */
-       if (ddata->rsts)
+       /* Balance use counts as PM runtime should have enabled these all */
+       if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
                reset_control_assert(ddata->rsts);
 
+       if (!(ddata->cfg.quirks &
+             (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) {
+               sysc_disable_main_clocks(ddata);
+               sysc_disable_opt_clocks(ddata);
+               sysc_clkdm_allow_idle(ddata);
+       }
+
        sysc_show_registers(ddata);
 
        ddata->dev->type = &sysc_device_type;
index f695588..4709864 100644 (file)
@@ -102,14 +102,13 @@ agp_segment_priv *agp_find_seg_in_client(const struct agp_client *client,
                                            int size, pgprot_t page_prot)
 {
        struct agp_segment_priv *seg;
-       int num_segments, i;
+       int i;
        off_t pg_start;
        size_t pg_count;
 
        pg_start = offset / 4096;
        pg_count = size / 4096;
        seg = *(client->segments);
-       num_segments = client->num_segments;
 
        for (i = 0; i < client->num_segments; i++) {
                if ((seg[i].pg_start == pg_start) &&
index df1edb5..ab154a7 100644 (file)
@@ -207,6 +207,7 @@ EXPORT_SYMBOL(agp_free_memory);
 /**
  *     agp_allocate_memory  -  allocate a group of pages of a certain type.
  *
+ *     @bridge: an agp_bridge_data struct allocated for the AGP host bridge.
  *     @page_count:    size_t argument of the number of pages
  *     @type:  u32 argument of the type of memory to be allocated.
  *
@@ -355,6 +356,7 @@ EXPORT_SYMBOL_GPL(agp_num_entries);
 /**
  *     agp_copy_info  -  copy bridge state information
  *
+ *     @bridge: an agp_bridge_data struct allocated for the AGP host bridge.
  *     @info:          agp_kern_info pointer.  The caller should insure that this pointer is valid.
  *
  *     This function copies information about the agp bridge device and the state of
@@ -850,7 +852,6 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 {
        char *table;
        char *table_end;
-       int size;
        int page_order;
        int num_entries;
        int i;
@@ -864,25 +865,22 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
        table = NULL;
        i = bridge->aperture_size_idx;
        temp = bridge->current_size;
-       size = page_order = num_entries = 0;
+       page_order = num_entries = 0;
 
        if (bridge->driver->size_type != FIXED_APER_SIZE) {
                do {
                        switch (bridge->driver->size_type) {
                        case U8_APER_SIZE:
-                               size = A_SIZE_8(temp)->size;
                                page_order =
                                    A_SIZE_8(temp)->page_order;
                                num_entries =
                                    A_SIZE_8(temp)->num_entries;
                                break;
                        case U16_APER_SIZE:
-                               size = A_SIZE_16(temp)->size;
                                page_order = A_SIZE_16(temp)->page_order;
                                num_entries = A_SIZE_16(temp)->num_entries;
                                break;
                        case U32_APER_SIZE:
-                               size = A_SIZE_32(temp)->size;
                                page_order = A_SIZE_32(temp)->page_order;
                                num_entries = A_SIZE_32(temp)->num_entries;
                                break;
@@ -890,7 +888,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
                        case FIXED_APER_SIZE:
                        case LVL2_APER_SIZE:
                        default:
-                               size = page_order = num_entries = 0;
+                               page_order = num_entries = 0;
                                break;
                        }
 
@@ -920,7 +918,6 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
                        }
                } while (!table && (i < bridge->driver->num_aperture_sizes));
        } else {
-               size = ((struct aper_size_info_fixed *) temp)->size;
                page_order = ((struct aper_size_info_fixed *) temp)->page_order;
                num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
                table = alloc_gatt_pages(page_order);
@@ -1282,6 +1279,7 @@ EXPORT_SYMBOL(agp_generic_destroy_page);
 /**
  * agp_enable  -  initialise the agp point-to-point connection.
  *
+ * @bridge: an agp_bridge_data struct allocated for the AGP host bridge.
  * @mode:      agp mode register value to configure with.
  */
 void agp_enable(struct agp_bridge_data *bridge, u32 mode)
index dc920da..45653a0 100644 (file)
@@ -299,6 +299,11 @@ config COMMON_CLK_STM32H7
        help
          Support for stm32h7 SoC family clocks
 
+config COMMON_CLK_MMP2
+       def_bool COMMON_CLK && (MACH_MMP2_DT || MACH_MMP3_DT)
+       help
+         Support for Marvell MMP2 and MMP3 SoC clocks
+
 config COMMON_CLK_BD718XX
        tristate "Clock driver for ROHM BD718x7 PMIC"
        depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528
index 7bc7ac6..acc141a 100644 (file)
@@ -8,7 +8,7 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
 obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
-obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
+obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
index 2dbbe47..7ed313a 100644 (file)
@@ -500,7 +500,7 @@ static int __init clk_rpmh_init(void)
 {
        return platform_driver_register(&clk_rpmh_driver);
 }
-subsys_initcall(clk_rpmh_init);
+core_initcall(clk_rpmh_init);
 
 static void __exit clk_rpmh_exit(void)
 {
index bd32212..9b0c4ce 100644 (file)
@@ -2855,7 +2855,7 @@ static int __init gcc_qcs404_init(void)
 {
        return platform_driver_register(&gcc_qcs404_driver);
 }
-subsys_initcall(gcc_qcs404_init);
+core_initcall(gcc_qcs404_init);
 
 static void __exit gcc_qcs404_exit(void)
 {
index d2142fe..f7b370f 100644 (file)
@@ -3628,7 +3628,7 @@ static int __init gcc_sdm845_init(void)
 {
        return platform_driver_register(&gcc_sdm845_driver);
 }
-subsys_initcall(gcc_sdm845_init);
+core_initcall(gcc_sdm845_init);
 
 static void __exit gcc_sdm845_exit(void)
 {
index 35b4f70..58151ca 100644 (file)
@@ -48,9 +48,9 @@ config PPC_PASEMI_CPUFREQ
          PWRficient processors.
 
 config POWERNV_CPUFREQ
-       tristate "CPU frequency scaling for IBM POWERNV platform"
-       depends on PPC_POWERNV
-       default y
-       help
+       tristate "CPU frequency scaling for IBM POWERNV platform"
+       depends on PPC_POWERNV
+       default y
+       help
         This adds support for CPU frequency switching on IBM POWERNV
         platform
index dfa6457..a652838 100644 (file)
@@ -4,17 +4,17 @@
 #
 
 config X86_INTEL_PSTATE
-       bool "Intel P state control"
-       depends on X86
-       select ACPI_PROCESSOR if ACPI
-       select ACPI_CPPC_LIB if X86_64 && ACPI && SCHED_MC_PRIO
-       help
-          This driver provides a P state for Intel core processors.
+       bool "Intel P state control"
+       depends on X86
+       select ACPI_PROCESSOR if ACPI
+       select ACPI_CPPC_LIB if X86_64 && ACPI && SCHED_MC_PRIO
+       help
+         This driver provides a P state for Intel core processors.
          The driver implements an internal governor and will become
-          the scaling driver and governor for Sandy bridge processors.
+         the scaling driver and governor for Sandy bridge processors.
 
          When this driver is enabled it will become the preferred
-          scaling driver for Sandy bridge processors.
+         scaling driver for Sandy bridge processors.
 
          If in doubt, say N.
 
index 54bc767..f1d170d 100644 (file)
@@ -180,4 +180,4 @@ create_pdev:
                               -1, data,
                               sizeof(struct cpufreq_dt_platform_data)));
 }
-device_initcall(cpufreq_dt_platdev_init);
+core_initcall(cpufreq_dt_platdev_init);
index b66e81c..737ff3b 100644 (file)
@@ -346,7 +346,7 @@ struct cpufreq_governor *cpufreq_default_governor(void)
        return CPU_FREQ_GOV_CONSERVATIVE;
 }
 
-fs_initcall(cpufreq_gov_dbs_init);
+core_initcall(cpufreq_gov_dbs_init);
 #else
 module_init(cpufreq_gov_dbs_init);
 #endif
index dced033..82a4d37 100644 (file)
@@ -483,7 +483,7 @@ struct cpufreq_governor *cpufreq_default_governor(void)
        return CPU_FREQ_GOV_ONDEMAND;
 }
 
-fs_initcall(cpufreq_gov_dbs_init);
+core_initcall(cpufreq_gov_dbs_init);
 #else
 module_init(cpufreq_gov_dbs_init);
 #endif
index aaa04df..def9afe 100644 (file)
@@ -50,5 +50,5 @@ MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'performance'");
 MODULE_LICENSE("GPL");
 
-fs_initcall(cpufreq_gov_performance_init);
+core_initcall(cpufreq_gov_performance_init);
 module_exit(cpufreq_gov_performance_exit);
index c143dc2..1ae6601 100644 (file)
@@ -43,7 +43,7 @@ struct cpufreq_governor *cpufreq_default_governor(void)
        return &cpufreq_gov_powersave;
 }
 
-fs_initcall(cpufreq_gov_powersave_init);
+core_initcall(cpufreq_gov_powersave_init);
 #else
 module_init(cpufreq_gov_powersave_init);
 #endif
index cbd81c5..b43e7cd 100644 (file)
@@ -147,7 +147,7 @@ struct cpufreq_governor *cpufreq_default_governor(void)
        return &cpufreq_gov_userspace;
 }
 
-fs_initcall(cpufreq_gov_userspace_init);
+core_initcall(cpufreq_gov_userspace_init);
 #else
 module_init(cpufreq_gov_userspace_init);
 #endif
index a9ae2f8..fc92a88 100644 (file)
@@ -334,7 +334,7 @@ static int __init qcom_cpufreq_hw_init(void)
 {
        return platform_driver_register(&qcom_cpufreq_hw_driver);
 }
-device_initcall(qcom_cpufreq_hw_init);
+postcore_initcall(qcom_cpufreq_hw_init);
 
 static void __exit qcom_cpufreq_hw_exit(void)
 {
index 4f0c637..7a1ea6f 100644 (file)
@@ -6,6 +6,7 @@
 #define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
 
 #include <linux/clk.h>
+#include <linux/cpufreq.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -128,8 +129,66 @@ out_put_np:
        return ret;
 }
 
+static int __maybe_unused tegra124_cpufreq_suspend(struct device *dev)
+{
+       struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+       int err;
+
+       /*
+        * PLLP rate 408Mhz is below the CPU Fmax at Vmin and is safe to
+        * use during suspend and resume. So, switch the CPU clock source
+        * to PLLP and disable DFLL.
+        */
+       err = clk_set_parent(priv->cpu_clk, priv->pllp_clk);
+       if (err < 0) {
+               dev_err(dev, "failed to reparent to PLLP: %d\n", err);
+               return err;
+       }
+
+       clk_disable_unprepare(priv->dfll_clk);
+
+       return 0;
+}
+
+static int __maybe_unused tegra124_cpufreq_resume(struct device *dev)
+{
+       struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+       int err;
+
+       /*
+        * Warmboot code powers up the CPU with PLLP clock source.
+        * Enable DFLL clock and switch CPU clock source back to DFLL.
+        */
+       err = clk_prepare_enable(priv->dfll_clk);
+       if (err < 0) {
+               dev_err(dev, "failed to enable DFLL clock for CPU: %d\n", err);
+               goto disable_cpufreq;
+       }
+
+       err = clk_set_parent(priv->cpu_clk, priv->dfll_clk);
+       if (err < 0) {
+               dev_err(dev, "failed to reparent to DFLL clock: %d\n", err);
+               goto disable_dfll;
+       }
+
+       return 0;
+
+disable_dfll:
+       clk_disable_unprepare(priv->dfll_clk);
+disable_cpufreq:
+       disable_cpufreq();
+
+       return err;
+}
+
+static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
+                               tegra124_cpufreq_resume)
+};
+
 static struct platform_driver tegra124_cpufreq_platdrv = {
        .driver.name    = "cpufreq-tegra124",
+       .driver.pm      = &tegra124_cpufreq_pm_ops,
        .probe          = tegra124_cpufreq_probe,
 };
 
index 506e3f2..83c85d3 100644 (file)
@@ -434,7 +434,7 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
        if (cur_cluster < MAX_CLUSTERS) {
                int cpu;
 
-               cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu));
+               dev_pm_opp_get_sharing_cpus(cpu_dev, policy->cpus);
 
                for_each_cpu(cpu, policy->cpus)
                        per_cpu(physical_cluster, cpu) = cur_cluster;
index 88727b7..c0aeedd 100644 (file)
@@ -16,7 +16,7 @@ config CPU_IDLE
 if CPU_IDLE
 
 config CPU_IDLE_MULTIPLE_DRIVERS
-        bool
+       bool
 
 config CPU_IDLE_GOV_LADDER
        bool "Ladder governor (for periodic timer tick)"
@@ -63,13 +63,13 @@ source "drivers/cpuidle/Kconfig.powerpc"
 endmenu
 
 config HALTPOLL_CPUIDLE
-       tristate "Halt poll cpuidle driver"
-       depends on X86 && KVM_GUEST
-       default y
-       help
-         This option enables halt poll cpuidle driver, which allows to poll
-         before halting in the guest (more efficient than polling in the
-         host via halt_poll_ns for some scenarios).
+       tristate "Halt poll cpuidle driver"
+       depends on X86 && KVM_GUEST
+       default y
+       help
+        This option enables halt poll cpuidle driver, which allows to poll
+        before halting in the guest (more efficient than polling in the
+        host via halt_poll_ns for some scenarios).
 
 endif
 
index d853047..a224d33 100644 (file)
@@ -3,15 +3,15 @@
 # ARM CPU Idle drivers
 #
 config ARM_CPUIDLE
-        bool "Generic ARM/ARM64 CPU idle Driver"
-        select DT_IDLE_STATES
+       bool "Generic ARM/ARM64 CPU idle Driver"
+       select DT_IDLE_STATES
        select CPU_IDLE_MULTIPLE_DRIVERS
-        help
-          Select this to enable generic cpuidle driver for ARM.
-          It provides a generic idle driver whose idle states are configured
-          at run-time through DT nodes. The CPUidle suspend backend is
-          initialized by calling the CPU operations init idle hook
-          provided by architecture code.
+       help
+         Select this to enable generic cpuidle driver for ARM.
+         It provides a generic idle driver whose idle states are configured
+         at run-time through DT nodes. The CPUidle suspend backend is
+         initialized by calling the CPU operations init idle hook
+         provided by architecture code.
 
 config ARM_PSCI_CPUIDLE
        bool "PSCI CPU idle Driver"
@@ -65,21 +65,21 @@ config ARM_U8500_CPUIDLE
        bool "Cpu Idle Driver for the ST-E u8500 processors"
        depends on ARCH_U8500 && !ARM64
        help
-         Select this to enable cpuidle for ST-E u8500 processors
+         Select this to enable cpuidle for ST-E u8500 processors.
 
 config ARM_AT91_CPUIDLE
        bool "Cpu Idle Driver for the AT91 processors"
        default y
        depends on ARCH_AT91 && !ARM64
        help
-         Select this to enable cpuidle for AT91 processors
+         Select this to enable cpuidle for AT91 processors.
 
 config ARM_EXYNOS_CPUIDLE
        bool "Cpu Idle Driver for the Exynos processors"
        depends on ARCH_EXYNOS && !ARM64
        select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
        help
-         Select this to enable cpuidle for Exynos processors
+         Select this to enable cpuidle for Exynos processors.
 
 config ARM_MVEBU_V7_CPUIDLE
        bool "CPU Idle Driver for mvebu v7 family processors"
index 569dbac..33d19c8 100644 (file)
@@ -381,7 +381,8 @@ u64 cpuidle_poll_time(struct cpuidle_driver *drv,
                if (dev->states_usage[i].disable)
                        continue;
 
-               limit_ns = (u64)drv->states[i].target_residency_ns;
+               limit_ns = drv->states[i].target_residency_ns;
+               break;
        }
 
        dev->poll_limit_ns = limit_ns;
@@ -572,7 +573,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
                return -EINVAL;
 
        for (i = 0; i < drv->state_count; i++)
-               if (drv->states[i].disabled)
+               if (drv->states[i].flags & CPUIDLE_FLAG_UNUSABLE)
                        dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER;
 
        per_cpu(cpuidle_devices, dev->cpu) = dev;
index c76423a..ce6a5f8 100644 (file)
@@ -403,6 +403,13 @@ void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
 
        mutex_lock(&cpuidle_lock);
 
+       spin_lock(&cpuidle_driver_lock);
+
+       if (!drv->cpumask) {
+               drv->states[idx].flags |= CPUIDLE_FLAG_UNUSABLE;
+               goto unlock;
+       }
+
        for_each_cpu(cpu, drv->cpumask) {
                struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
 
@@ -415,5 +422,8 @@ void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
                        dev->states_usage[idx].disable &= ~CPUIDLE_STATE_DISABLED_BY_DRIVER;
        }
 
+unlock:
+       spin_unlock(&cpuidle_driver_lock);
+
        mutex_unlock(&cpuidle_lock);
 }
index 9f1ace9..f7e8361 100644 (file)
@@ -53,7 +53,6 @@ void cpuidle_poll_state_init(struct cpuidle_driver *drv)
        state->target_residency_ns = 0;
        state->power_usage = -1;
        state->enter = poll_idle;
-       state->disabled = false;
        state->flags = CPUIDLE_FLAG_POLLING;
 }
 EXPORT_SYMBOL_GPL(cpuidle_poll_state_init);
index f840e61..57f6944 100644 (file)
 #include <linux/printk.h>
 #include <linux/hrtimer.h>
 #include <linux/of.h>
+#include <linux/pm_qos.h>
 #include "governor.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/devfreq.h>
 
+#define HZ_PER_KHZ     1000
+
 static struct class *devfreq_class;
 
 /*
@@ -99,6 +102,54 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq)
 }
 
 /**
+ * get_freq_range() - Get the current freq range
+ * @devfreq:   the devfreq instance
+ * @min_freq:  the min frequency
+ * @max_freq:  the max frequency
+ *
+ * This takes into consideration all constraints.
+ */
+static void get_freq_range(struct devfreq *devfreq,
+                          unsigned long *min_freq,
+                          unsigned long *max_freq)
+{
+       unsigned long *freq_table = devfreq->profile->freq_table;
+       s32 qos_min_freq, qos_max_freq;
+
+       lockdep_assert_held(&devfreq->lock);
+
+       /*
+        * Initialize minimum/maximum frequency from freq table.
+        * The devfreq drivers can initialize this in either ascending or
+        * descending order and devfreq core supports both.
+        */
+       if (freq_table[0] < freq_table[devfreq->profile->max_state - 1]) {
+               *min_freq = freq_table[0];
+               *max_freq = freq_table[devfreq->profile->max_state - 1];
+       } else {
+               *min_freq = freq_table[devfreq->profile->max_state - 1];
+               *max_freq = freq_table[0];
+       }
+
+       /* Apply constraints from PM QoS */
+       qos_min_freq = dev_pm_qos_read_value(devfreq->dev.parent,
+                                            DEV_PM_QOS_MIN_FREQUENCY);
+       qos_max_freq = dev_pm_qos_read_value(devfreq->dev.parent,
+                                            DEV_PM_QOS_MAX_FREQUENCY);
+       *min_freq = max(*min_freq, (unsigned long)HZ_PER_KHZ * qos_min_freq);
+       if (qos_max_freq != PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE)
+               *max_freq = min(*max_freq,
+                               (unsigned long)HZ_PER_KHZ * qos_max_freq);
+
+       /* Apply constraints from OPP interface */
+       *min_freq = max(*min_freq, devfreq->scaling_min_freq);
+       *max_freq = min(*max_freq, devfreq->scaling_max_freq);
+
+       if (*min_freq > *max_freq)
+               *min_freq = *max_freq;
+}
+
+/**
  * devfreq_get_freq_level() - Lookup freq_table for the frequency
  * @devfreq:   the devfreq instance
  * @freq:      the target frequency
@@ -351,16 +402,7 @@ int update_devfreq(struct devfreq *devfreq)
        err = devfreq->governor->get_target_freq(devfreq, &freq);
        if (err)
                return err;
-
-       /*
-        * Adjust the frequency with user freq, QoS and available freq.
-        *
-        * List from the highest priority
-        * max_freq
-        * min_freq
-        */
-       max_freq = min(devfreq->scaling_max_freq, devfreq->max_freq);
-       min_freq = max(devfreq->scaling_min_freq, devfreq->min_freq);
+       get_freq_range(devfreq, &min_freq, &max_freq);
 
        if (freq < min_freq) {
                freq = min_freq;
@@ -568,26 +610,69 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
                                 void *devp)
 {
        struct devfreq *devfreq = container_of(nb, struct devfreq, nb);
-       int ret;
+       int err = -EINVAL;
 
        mutex_lock(&devfreq->lock);
 
        devfreq->scaling_min_freq = find_available_min_freq(devfreq);
-       if (!devfreq->scaling_min_freq) {
-               mutex_unlock(&devfreq->lock);
-               return -EINVAL;
-       }
+       if (!devfreq->scaling_min_freq)
+               goto out;
 
        devfreq->scaling_max_freq = find_available_max_freq(devfreq);
        if (!devfreq->scaling_max_freq) {
-               mutex_unlock(&devfreq->lock);
-               return -EINVAL;
+               devfreq->scaling_max_freq = ULONG_MAX;
+               goto out;
        }
 
-       ret = update_devfreq(devfreq);
+       err = update_devfreq(devfreq);
+
+out:
        mutex_unlock(&devfreq->lock);
+       if (err)
+               dev_err(devfreq->dev.parent,
+                       "failed to update frequency from OPP notifier (%d)\n",
+                       err);
 
-       return ret;
+       return NOTIFY_OK;
+}
+
+/**
+ * qos_notifier_call() - Common handler for QoS constraints.
+ * @devfreq:    the devfreq instance.
+ */
+static int qos_notifier_call(struct devfreq *devfreq)
+{
+       int err;
+
+       mutex_lock(&devfreq->lock);
+       err = update_devfreq(devfreq);
+       mutex_unlock(&devfreq->lock);
+       if (err)
+               dev_err(devfreq->dev.parent,
+                       "failed to update frequency from PM QoS (%d)\n",
+                       err);
+
+       return NOTIFY_OK;
+}
+
+/**
+ * qos_min_notifier_call() - Callback for QoS min_freq changes.
+ * @nb:                Should be devfreq->nb_min
+ */
+static int qos_min_notifier_call(struct notifier_block *nb,
+                                        unsigned long val, void *ptr)
+{
+       return qos_notifier_call(container_of(nb, struct devfreq, nb_min));
+}
+
+/**
+ * qos_max_notifier_call() - Callback for QoS max_freq changes.
+ * @nb:                Should be devfreq->nb_max
+ */
+static int qos_max_notifier_call(struct notifier_block *nb,
+                                        unsigned long val, void *ptr)
+{
+       return qos_notifier_call(container_of(nb, struct devfreq, nb_max));
 }
 
 /**
@@ -599,16 +684,36 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
 static void devfreq_dev_release(struct device *dev)
 {
        struct devfreq *devfreq = to_devfreq(dev);
+       int err;
 
        mutex_lock(&devfreq_list_lock);
-       if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) {
-               mutex_unlock(&devfreq_list_lock);
-               dev_warn(&devfreq->dev, "releasing devfreq which doesn't exist\n");
-               return;
-       }
        list_del(&devfreq->node);
        mutex_unlock(&devfreq_list_lock);
 
+       err = dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
+                                        DEV_PM_QOS_MAX_FREQUENCY);
+       if (err && err != -ENOENT)
+               dev_warn(dev->parent,
+                       "Failed to remove max_freq notifier: %d\n", err);
+       err = dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
+                                        DEV_PM_QOS_MIN_FREQUENCY);
+       if (err && err != -ENOENT)
+               dev_warn(dev->parent,
+                       "Failed to remove min_freq notifier: %d\n", err);
+
+       if (dev_pm_qos_request_active(&devfreq->user_max_freq_req)) {
+               err = dev_pm_qos_remove_request(&devfreq->user_max_freq_req);
+               if (err)
+                       dev_warn(dev->parent,
+                               "Failed to remove max_freq request: %d\n", err);
+       }
+       if (dev_pm_qos_request_active(&devfreq->user_min_freq_req)) {
+               err = dev_pm_qos_remove_request(&devfreq->user_min_freq_req);
+               if (err)
+                       dev_warn(dev->parent,
+                               "Failed to remove min_freq request: %d\n", err);
+       }
+
        if (devfreq->profile->exit)
                devfreq->profile->exit(devfreq->dev.parent);
 
@@ -660,6 +765,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
        devfreq->dev.parent = dev;
        devfreq->dev.class = devfreq_class;
        devfreq->dev.release = devfreq_dev_release;
+       INIT_LIST_HEAD(&devfreq->node);
        devfreq->profile = profile;
        strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
        devfreq->previous_freq = profile->initial_freq;
@@ -681,7 +787,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
                err = -EINVAL;
                goto err_dev;
        }
-       devfreq->min_freq = devfreq->scaling_min_freq;
 
        devfreq->scaling_max_freq = find_available_max_freq(devfreq);
        if (!devfreq->scaling_max_freq) {
@@ -689,7 +794,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
                err = -EINVAL;
                goto err_dev;
        }
-       devfreq->max_freq = devfreq->scaling_max_freq;
 
        devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev);
        atomic_set(&devfreq->suspend_count, 0);
@@ -730,6 +834,28 @@ struct devfreq *devfreq_add_device(struct device *dev,
 
        mutex_unlock(&devfreq->lock);
 
+       err = dev_pm_qos_add_request(dev, &devfreq->user_min_freq_req,
+                                    DEV_PM_QOS_MIN_FREQUENCY, 0);
+       if (err < 0)
+               goto err_devfreq;
+       err = dev_pm_qos_add_request(dev, &devfreq->user_max_freq_req,
+                                    DEV_PM_QOS_MAX_FREQUENCY,
+                                    PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
+       if (err < 0)
+               goto err_devfreq;
+
+       devfreq->nb_min.notifier_call = qos_min_notifier_call;
+       err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_min,
+                                     DEV_PM_QOS_MIN_FREQUENCY);
+       if (err)
+               goto err_devfreq;
+
+       devfreq->nb_max.notifier_call = qos_max_notifier_call;
+       err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_max,
+                                     DEV_PM_QOS_MAX_FREQUENCY);
+       if (err)
+               goto err_devfreq;
+
        mutex_lock(&devfreq_list_lock);
 
        governor = try_then_request_governor(devfreq->governor_name);
@@ -921,7 +1047,9 @@ int devfreq_suspend_device(struct devfreq *devfreq)
        }
 
        if (devfreq->suspend_freq) {
+               mutex_lock(&devfreq->lock);
                ret = devfreq_set_target(devfreq, devfreq->suspend_freq, 0);
+               mutex_unlock(&devfreq->lock);
                if (ret)
                        return ret;
        }
@@ -949,7 +1077,9 @@ int devfreq_resume_device(struct devfreq *devfreq)
                return 0;
 
        if (devfreq->resume_freq) {
+               mutex_lock(&devfreq->lock);
                ret = devfreq_set_target(devfreq, devfreq->resume_freq, 0);
+               mutex_unlock(&devfreq->lock);
                if (ret)
                        return ret;
        }
@@ -1299,41 +1429,37 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
        unsigned long value;
        int ret;
 
+       /*
+        * Protect against theoretical sysfs writes between
+        * device_add and dev_pm_qos_add_request
+        */
+       if (!dev_pm_qos_request_active(&df->user_min_freq_req))
+               return -EAGAIN;
+
        ret = sscanf(buf, "%lu", &value);
        if (ret != 1)
                return -EINVAL;
 
-       mutex_lock(&df->lock);
-
-       if (value) {
-               if (value > df->max_freq) {
-                       ret = -EINVAL;
-                       goto unlock;
-               }
-       } else {
-               unsigned long *freq_table = df->profile->freq_table;
-
-               /* Get minimum frequency according to sorting order */
-               if (freq_table[0] < freq_table[df->profile->max_state - 1])
-                       value = freq_table[0];
-               else
-                       value = freq_table[df->profile->max_state - 1];
-       }
+       /* Round down to kHz for PM QoS */
+       ret = dev_pm_qos_update_request(&df->user_min_freq_req,
+                                       value / HZ_PER_KHZ);
+       if (ret < 0)
+               return ret;
 
-       df->min_freq = value;
-       update_devfreq(df);
-       ret = count;
-unlock:
-       mutex_unlock(&df->lock);
-       return ret;
+       return count;
 }
 
 static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
 {
        struct devfreq *df = to_devfreq(dev);
+       unsigned long min_freq, max_freq;
+
+       mutex_lock(&df->lock);
+       get_freq_range(df, &min_freq, &max_freq);
+       mutex_unlock(&df->lock);
 
-       return sprintf(buf, "%lu\n", max(df->scaling_min_freq, df->min_freq));
+       return sprintf(buf, "%lu\n", min_freq);
 }
 
 static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
@@ -1343,33 +1469,37 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
        unsigned long value;
        int ret;
 
+       /*
+        * Protect against theoretical sysfs writes between
+        * device_add and dev_pm_qos_add_request
+        */
+       if (!dev_pm_qos_request_active(&df->user_max_freq_req))
+               return -EINVAL;
+
        ret = sscanf(buf, "%lu", &value);
        if (ret != 1)
                return -EINVAL;
 
-       mutex_lock(&df->lock);
-
-       if (value) {
-               if (value < df->min_freq) {
-                       ret = -EINVAL;
-                       goto unlock;
-               }
-       } else {
-               unsigned long *freq_table = df->profile->freq_table;
+       /*
+        * PM QoS frequencies are in kHz so we need to convert. Convert by
+        * rounding upwards so that the acceptable interval never shrinks.
+        *
+        * For example if the user writes "666666666" to sysfs this value will
+        * be converted to 666667 kHz and back to 666667000 Hz before an OPP
+        * lookup, this ensures that an OPP of 666666666Hz is still accepted.
+        *
+        * A value of zero means "no limit".
+        */
+       if (value)
+               value = DIV_ROUND_UP(value, HZ_PER_KHZ);
+       else
+               value = PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;
 
-               /* Get maximum frequency according to sorting order */
-               if (freq_table[0] < freq_table[df->profile->max_state - 1])
-                       value = freq_table[df->profile->max_state - 1];
-               else
-                       value = freq_table[0];
-       }
+       ret = dev_pm_qos_update_request(&df->user_max_freq_req, value);
+       if (ret < 0)
+               return ret;
 
-       df->max_freq = value;
-       update_devfreq(df);
-       ret = count;
-unlock:
-       mutex_unlock(&df->lock);
-       return ret;
+       return count;
 }
 static DEVICE_ATTR_RW(min_freq);
 
@@ -1377,8 +1507,13 @@ static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
 {
        struct devfreq *df = to_devfreq(dev);
+       unsigned long min_freq, max_freq;
+
+       mutex_lock(&df->lock);
+       get_freq_range(df, &min_freq, &max_freq);
+       mutex_unlock(&df->lock);
 
-       return sprintf(buf, "%lu\n", min(df->scaling_max_freq, df->max_freq));
+       return sprintf(buf, "%lu\n", max_freq);
 }
 static DEVICE_ATTR_RW(max_freq);
 
index 76fb072..5a5a1da 100644 (file)
@@ -221,7 +221,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
        a_fences = get_fences(a, &a_num_fences);
        b_fences = get_fences(b, &b_num_fences);
        if (a_num_fences > INT_MAX - b_num_fences)
-               return NULL;
+               goto err;
 
        num_fences = a_num_fences + b_num_fences;
 
index 92f843e..7a30952 100644 (file)
@@ -135,8 +135,10 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
                return NULL;
 
        id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
-       if (id < 0)
-               goto free_mem;
+       if (id < 0) {
+               kfree(scmi_dev);
+               return NULL;
+       }
 
        scmi_dev->id = id;
        scmi_dev->protocol_id = protocol;
@@ -154,8 +156,6 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
 put_dev:
        put_device(&scmi_dev->dev);
        ida_simple_remove(&scmi_bus_id, id);
-free_mem:
-       kfree(scmi_dev);
        return NULL;
 }
 
index 4a8012e..601af4e 100644 (file)
@@ -323,7 +323,7 @@ static void scmi_perf_fc_ring_db(struct scmi_fc_db_info *db)
 
                if (db->mask)
                        val = ioread64_hi_lo(db->addr) & db->mask;
-               iowrite64_hi_lo(db->set, db->addr);
+               iowrite64_hi_lo(db->set | val, db->addr);
        }
 #endif
 }
index b096195..2b02cb1 100644 (file)
@@ -681,7 +681,7 @@ device_initcall(efi_load_efivars);
                { name },                                  \
                { prop },                                  \
                offsetof(struct efi_fdt_params, field),    \
-               FIELD_SIZEOF(struct efi_fdt_params, field) \
+               sizeof_field(struct efi_fdt_params, field) \
        }
 
 struct params {
index a43d2db..4265e9d 100644 (file)
@@ -114,7 +114,7 @@ static int imx_dsp_probe(struct platform_device *pdev)
 
        dev_info(dev, "NXP i.MX DSP IPC initialized\n");
 
-       return devm_of_platform_populate(dev);
+       return 0;
 out:
        kfree(chan_name);
        for (j = 0; j < i; j++) {
index 687121f..db655e8 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <dt-bindings/firmware/imx/rsrc.h>
 #include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/sci.h>
 #include <linux/mailbox_client.h>
 
 #define IMX_SC_IRQ_FUNC_ENABLE 1
index 04a24a8..03b43b7 100644 (file)
@@ -107,6 +107,12 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
        struct imx_sc_rpc_msg *hdr;
        u32 *data = msg;
 
+       if (!sc_ipc->msg) {
+               dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n",
+                               sc_chan->idx, *data);
+               return;
+       }
+
        if (sc_chan->idx == 0) {
                hdr = msg;
                sc_ipc->rx_size = hdr->size;
@@ -156,6 +162,7 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
  */
 int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
 {
+       uint8_t saved_svc, saved_func;
        struct imx_sc_rpc_msg *hdr;
        int ret;
 
@@ -165,7 +172,11 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
        mutex_lock(&sc_ipc->lock);
        reinit_completion(&sc_ipc->done);
 
-       sc_ipc->msg = msg;
+       if (have_resp) {
+               sc_ipc->msg = msg;
+               saved_svc = ((struct imx_sc_rpc_msg *)msg)->svc;
+               saved_func = ((struct imx_sc_rpc_msg *)msg)->func;
+       }
        sc_ipc->count = 0;
        ret = imx_scu_ipc_write(sc_ipc, msg);
        if (ret < 0) {
@@ -184,9 +195,20 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
                /* response status is stored in hdr->func field */
                hdr = msg;
                ret = hdr->func;
+               /*
+                * Some special SCU firmware APIs do NOT have return value
+                * in hdr->func, but they do have response data, those special
+                * APIs are defined as void function in SCU firmware, so they
+                * should be treated as return success always.
+                */
+               if ((saved_svc == IMX_SC_RPC_SVC_MISC) &&
+                       (saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID ||
+                        saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS))
+                       ret = 0;
        }
 
 out:
+       sc_ipc->msg = NULL;
        mutex_unlock(&sc_ipc->lock);
 
        dev_dbg(sc_ipc->dev, "RPC SVC done\n");
index 8d908a8..1d5b4d7 100644 (file)
@@ -35,7 +35,7 @@ struct meson_sm_chip {
        struct meson_sm_cmd cmd[];
 };
 
-struct meson_sm_chip gxbb_chip = {
+static const struct meson_sm_chip gxbb_chip = {
        .shmem_size             = SZ_4K,
        .cmd_shmem_in_base      = 0x82000020,
        .cmd_shmem_out_base     = 0x82000021,
@@ -54,8 +54,6 @@ struct meson_sm_firmware {
        void __iomem *sm_shmem_out_base;
 };
 
-static struct meson_sm_firmware fw;
-
 static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
                            unsigned int cmd_index)
 {
@@ -90,6 +88,7 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
 /**
  * meson_sm_call - generic SMC32 call to the secure-monitor
  *
+ * @fw:                Pointer to secure-monitor firmware
  * @cmd_index: Index of the SMC32 function ID
  * @ret:       Returned value
  * @arg0:      SMC32 Argument 0
@@ -100,15 +99,15 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
  *
  * Return:     0 on success, a negative value on error
  */
-int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0,
-                 u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
+                 u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
 {
        u32 cmd, lret;
 
-       if (!fw.chip)
+       if (!fw->chip)
                return -ENOENT;
 
-       cmd = meson_sm_get_cmd(fw.chip, cmd_index);
+       cmd = meson_sm_get_cmd(fw->chip, cmd_index);
        if (!cmd)
                return -EINVAL;
 
@@ -124,6 +123,7 @@ EXPORT_SYMBOL(meson_sm_call);
 /**
  * meson_sm_call_read - retrieve data from secure-monitor
  *
+ * @fw:                Pointer to secure-monitor firmware
  * @buffer:    Buffer to store the retrieved data
  * @bsize:     Size of the buffer
  * @cmd_index: Index of the SMC32 function ID
@@ -137,22 +137,23 @@ EXPORT_SYMBOL(meson_sm_call);
  *             When 0 is returned there is no guarantee about the amount of
  *             data read and bsize bytes are copied in buffer.
  */
-int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
-                      u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
+                      unsigned int bsize, unsigned int cmd_index, u32 arg0,
+                      u32 arg1, u32 arg2, u32 arg3, u32 arg4)
 {
        u32 size;
        int ret;
 
-       if (!fw.chip)
+       if (!fw->chip)
                return -ENOENT;
 
-       if (!fw.chip->cmd_shmem_out_base)
+       if (!fw->chip->cmd_shmem_out_base)
                return -EINVAL;
 
-       if (bsize > fw.chip->shmem_size)
+       if (bsize > fw->chip->shmem_size)
                return -EINVAL;
 
-       if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
+       if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
                return -EINVAL;
 
        if (size > bsize)
@@ -164,7 +165,7 @@ int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
                size = bsize;
 
        if (buffer)
-               memcpy(buffer, fw.sm_shmem_out_base, size);
+               memcpy(buffer, fw->sm_shmem_out_base, size);
 
        return ret;
 }
@@ -173,6 +174,7 @@ EXPORT_SYMBOL(meson_sm_call_read);
 /**
  * meson_sm_call_write - send data to secure-monitor
  *
+ * @fw:                Pointer to secure-monitor firmware
  * @buffer:    Buffer containing data to send
  * @size:      Size of the data to send
  * @cmd_index: Index of the SMC32 function ID
@@ -184,23 +186,24 @@ EXPORT_SYMBOL(meson_sm_call_read);
  *
  * Return:     size of sent data on success, a negative value on error
  */
-int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
-                       u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+                       unsigned int size, unsigned int cmd_index, u32 arg0,
+                       u32 arg1, u32 arg2, u32 arg3, u32 arg4)
 {
        u32 written;
 
-       if (!fw.chip)
+       if (!fw->chip)
                return -ENOENT;
 
-       if (size > fw.chip->shmem_size)
+       if (size > fw->chip->shmem_size)
                return -EINVAL;
 
-       if (!fw.chip->cmd_shmem_in_base)
+       if (!fw->chip->cmd_shmem_in_base)
                return -EINVAL;
 
-       memcpy(fw.sm_shmem_in_base, buffer, size);
+       memcpy(fw->sm_shmem_in_base, buffer, size);
 
-       if (meson_sm_call(cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
+       if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
                return -EINVAL;
 
        if (!written)
@@ -210,6 +213,24 @@ int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
 }
 EXPORT_SYMBOL(meson_sm_call_write);
 
+/**
+ * meson_sm_get - get pointer to meson_sm_firmware structure.
+ *
+ * @sm_node:           Pointer to the secure-monitor Device Tree node.
+ *
+ * Return:             NULL is the secure-monitor device is not ready.
+ */
+struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
+{
+       struct platform_device *pdev = of_find_device_by_node(sm_node);
+
+       if (!pdev)
+               return NULL;
+
+       return platform_get_drvdata(pdev);
+}
+EXPORT_SYMBOL_GPL(meson_sm_get);
+
 #define SM_CHIP_ID_LENGTH      119
 #define SM_CHIP_ID_OFFSET      4
 #define SM_CHIP_ID_SIZE                12
@@ -217,33 +238,25 @@ EXPORT_SYMBOL(meson_sm_call_write);
 static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
                         char *buf)
 {
+       struct platform_device *pdev = to_platform_device(dev);
+       struct meson_sm_firmware *fw;
        uint8_t *id_buf;
        int ret;
 
+       fw = platform_get_drvdata(pdev);
+
        id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL);
        if (!id_buf)
                return -ENOMEM;
 
-       ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
+       ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
                                 0, 0, 0, 0, 0);
        if (ret < 0) {
                kfree(id_buf);
                return ret;
        }
 
-       ret = sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-                       id_buf[SM_CHIP_ID_OFFSET + 0],
-                       id_buf[SM_CHIP_ID_OFFSET + 1],
-                       id_buf[SM_CHIP_ID_OFFSET + 2],
-                       id_buf[SM_CHIP_ID_OFFSET + 3],
-                       id_buf[SM_CHIP_ID_OFFSET + 4],
-                       id_buf[SM_CHIP_ID_OFFSET + 5],
-                       id_buf[SM_CHIP_ID_OFFSET + 6],
-                       id_buf[SM_CHIP_ID_OFFSET + 7],
-                       id_buf[SM_CHIP_ID_OFFSET + 8],
-                       id_buf[SM_CHIP_ID_OFFSET + 9],
-                       id_buf[SM_CHIP_ID_OFFSET + 10],
-                       id_buf[SM_CHIP_ID_OFFSET + 11]);
+       ret = sprintf(buf, "%12phN\n", &id_buf[SM_CHIP_ID_OFFSET]);
 
        kfree(id_buf);
 
@@ -268,25 +281,34 @@ static const struct of_device_id meson_sm_ids[] = {
 
 static int __init meson_sm_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        const struct meson_sm_chip *chip;
+       struct meson_sm_firmware *fw;
+
+       fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
+       if (!fw)
+               return -ENOMEM;
 
-       chip = of_match_device(meson_sm_ids, &pdev->dev)->data;
+       chip = of_match_device(meson_sm_ids, dev)->data;
 
        if (chip->cmd_shmem_in_base) {
-               fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
-                                                        chip->shmem_size);
-               if (WARN_ON(!fw.sm_shmem_in_base))
+               fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
+                                                         chip->shmem_size);
+               if (WARN_ON(!fw->sm_shmem_in_base))
                        goto out;
        }
 
        if (chip->cmd_shmem_out_base) {
-               fw.sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
-                                                         chip->shmem_size);
-               if (WARN_ON(!fw.sm_shmem_out_base))
+               fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
+                                                          chip->shmem_size);
+               if (WARN_ON(!fw->sm_shmem_out_base))
                        goto out_in_base;
        }
 
-       fw.chip = chip;
+       fw->chip = chip;
+
+       platform_set_drvdata(pdev, fw);
+
        pr_info("secure-monitor enabled\n");
 
        if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group))
@@ -295,7 +317,7 @@ static int __init meson_sm_probe(struct platform_device *pdev)
        return 0;
 
 out_in_base:
-       iounmap(fw.sm_shmem_in_base);
+       iounmap(fw->sm_shmem_in_base);
 out:
        return -EINVAL;
 }
index bee8729..48e2ef7 100644 (file)
@@ -442,6 +442,41 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
                req, req_cnt * sizeof(*req), resp, sizeof(*resp));
 }
 
+int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size,
+                         u32 mode)
+{
+       struct ocmem_tz_lock {
+               __le32 id;
+               __le32 offset;
+               __le32 size;
+               __le32 mode;
+       } request;
+
+       request.id = cpu_to_le32(id);
+       request.offset = cpu_to_le32(offset);
+       request.size = cpu_to_le32(size);
+       request.mode = cpu_to_le32(mode);
+
+       return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD,
+                            &request, sizeof(request), NULL, 0);
+}
+
+int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size)
+{
+       struct ocmem_tz_unlock {
+               __le32 id;
+               __le32 offset;
+               __le32 size;
+       } request;
+
+       request.id = cpu_to_le32(id);
+       request.offset = cpu_to_le32(offset);
+       request.size = cpu_to_le32(size);
+
+       return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD,
+                            &request, sizeof(request), NULL, 0);
+}
+
 void __qcom_scm_init(void)
 {
 }
@@ -582,7 +617,22 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,
 int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
                               u32 spare)
 {
-       return -ENODEV;
+       struct msm_scm_sec_cfg {
+               __le32 id;
+               __le32 ctx_bank_num;
+       } cfg;
+       int ret, scm_ret = 0;
+
+       cfg.id = cpu_to_le32(device_id);
+       cfg.ctx_bank_num = cpu_to_le32(spare);
+
+       ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG,
+                           &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret));
+
+       if (ret || scm_ret)
+               return ret ? ret : -EINVAL;
+
+       return 0;
 }
 
 int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare,
index e1cd933..3c58503 100644 (file)
@@ -291,6 +291,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
        return ret;
 }
 
+int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset,
+                         uint32_t size, uint32_t mode)
+{
+       return -ENOTSUPP;
+}
+
+int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset,
+                           uint32_t size)
+{
+       return -ENOTSUPP;
+}
+
 void __qcom_scm_init(void)
 {
        u64 cmd;
index a729e05..1ba0df4 100644 (file)
@@ -192,6 +192,46 @@ bool qcom_scm_pas_supported(u32 peripheral)
 EXPORT_SYMBOL(qcom_scm_pas_supported);
 
 /**
+ * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available
+ */
+bool qcom_scm_ocmem_lock_available(void)
+{
+       return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC,
+                                           QCOM_SCM_OCMEM_LOCK_CMD);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_lock_available);
+
+/**
+ * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM
+ * region to the specified initiator
+ *
+ * @id:     tz initiator id
+ * @offset: OCMEM offset
+ * @size:   OCMEM size
+ * @mode:   access mode (WIDE/NARROW)
+ */
+int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size,
+                       u32 mode)
+{
+       return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_lock);
+
+/**
+ * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM
+ * region from the specified initiator
+ *
+ * @id:     tz initiator id
+ * @offset: OCMEM offset
+ * @size:   OCMEM size
+ */
+int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size)
+{
+       return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_unlock);
+
+/**
  * qcom_scm_pas_init_image() - Initialize peripheral authentication service
  *                            state machine for a given peripheral, using the
  *                            metadata
@@ -327,6 +367,19 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = {
        .deassert = qcom_scm_pas_reset_deassert,
 };
 
+/**
+ * qcom_scm_restore_sec_cfg_available() - Check if secure environment
+ * supports restore security config interface.
+ *
+ * Return true if restore-cfg interface is supported, false if not.
+ */
+bool qcom_scm_restore_sec_cfg_available(void)
+{
+       return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+                                           QCOM_SCM_RESTORE_SEC_CFG);
+}
+EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available);
+
 int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare)
 {
        return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare);
index baee744..81dcf5f 100644 (file)
@@ -42,6 +42,15 @@ extern int __qcom_scm_hdcp_req(struct device *dev,
 
 extern void __qcom_scm_init(void);
 
+#define QCOM_SCM_OCMEM_SVC                     0xf
+#define QCOM_SCM_OCMEM_LOCK_CMD                0x1
+#define QCOM_SCM_OCMEM_UNLOCK_CMD              0x2
+
+extern int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset,
+                                u32 size, u32 mode);
+extern int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset,
+                                  u32 size);
+
 #define QCOM_SCM_SVC_PIL               0x2
 #define QCOM_SCM_PAS_INIT_IMAGE_CMD    0x1
 #define QCOM_SCM_PAS_MEM_SETUP_CMD     0x2
index 19c5613..6741fcd 100644 (file)
@@ -804,7 +804,7 @@ static int __maybe_unused tegra_bpmp_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops tegra_bpmp_pm_ops = {
-       .resume_early = tegra_bpmp_resume,
+       .resume_noirq = tegra_bpmp_resume,
 };
 
 #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
index fd3d837..75bdfaa 100644 (file)
@@ -711,8 +711,11 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
        int ret;
 
        np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp");
-       if (!np)
-               return 0;
+       if (!np) {
+               np = of_find_compatible_node(NULL, NULL, "xlnx,versal");
+               if (!np)
+                       return 0;
+       }
        of_node_put(np);
 
        ret = get_set_conduit_method(dev->of_node);
@@ -770,6 +773,7 @@ static int zynqmp_firmware_remove(struct platform_device *pdev)
 
 static const struct of_device_id zynqmp_firmware_of_match[] = {
        {.compatible = "xlnx,zynqmp-firmware"},
+       {.compatible = "xlnx,versal-firmware"},
        {},
 };
 MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match);
index 400c09b..1f7d9bb 100644 (file)
@@ -178,46 +178,25 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset)
        return !!(port_state & mask);
 }
 
+static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
+
 static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
        unsigned long *bits)
 {
        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
-       size_t i;
-       static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
-       const unsigned int gpio_reg_size = 8;
-       unsigned int bits_offset;
-       size_t word_index;
-       unsigned int word_offset;
-       unsigned long word_mask;
-       const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+       unsigned long offset;
+       unsigned long gpio_mask;
+       unsigned int port_addr;
        unsigned long port_state;
 
        /* clear bits array to a clean slate */
        bitmap_zero(bits, chip->ngpio);
 
-       /* get bits are evaluated a gpio port register at a time */
-       for (i = 0; i < ARRAY_SIZE(ports); i++) {
-               /* gpio offset in bits array */
-               bits_offset = i * gpio_reg_size;
-
-               /* word index for bits array */
-               word_index = BIT_WORD(bits_offset);
-
-               /* gpio offset within current word of bits array */
-               word_offset = bits_offset % BITS_PER_LONG;
-
-               /* mask of get bits for current gpio within current word */
-               word_mask = mask[word_index] & (port_mask << word_offset);
-               if (!word_mask) {
-                       /* no get bits in this port so skip to next one */
-                       continue;
-               }
-
-               /* read bits from current gpio port */
-               port_state = inb(dio48egpio->base + ports[i]);
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               port_addr = dio48egpio->base + ports[offset / 8];
+               port_state = inb(port_addr) & gpio_mask;
 
-               /* store acquired bits at respective bits array offset */
-               bits[word_index] |= (port_state << word_offset) & word_mask;
+               bitmap_set_value8(bits, port_state, offset);
        }
 
        return 0;
@@ -247,37 +226,27 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
-       unsigned int i;
-       const unsigned int gpio_reg_size = 8;
-       unsigned int port;
-       unsigned int out_port;
-       unsigned int bitmask;
+       unsigned long offset;
+       unsigned long gpio_mask;
+       size_t index;
+       unsigned int port_addr;
+       unsigned long bitmask;
        unsigned long flags;
 
-       /* set bits are evaluated a gpio register size at a time */
-       for (i = 0; i < chip->ngpio; i += gpio_reg_size) {
-               /* no more set bits in this mask word; skip to the next word */
-               if (!mask[BIT_WORD(i)]) {
-                       i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size;
-                       continue;
-               }
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               index = offset / 8;
+               port_addr = dio48egpio->base + ports[index];
 
-               port = i / gpio_reg_size;
-               out_port = (port > 2) ? port + 1 : port;
-               bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
+               bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
 
                raw_spin_lock_irqsave(&dio48egpio->lock, flags);
 
                /* update output state data and set device gpio register */
-               dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)];
-               dio48egpio->out_state[port] |= bitmask;
-               outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
+               dio48egpio->out_state[index] &= ~gpio_mask;
+               dio48egpio->out_state[index] |= bitmask;
+               outb(dio48egpio->out_state[index], port_addr);
 
                raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
-
-               /* prepare for next gpio register set */
-               mask[BIT_WORD(i)] >>= gpio_reg_size;
-               bits[BIT_WORD(i)] >>= gpio_reg_size;
        }
 }
 
index c50329a..d350ac0 100644 (file)
@@ -85,42 +85,20 @@ static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
        unsigned long *bits)
 {
        struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
-       size_t i;
+       unsigned long offset;
+       unsigned long gpio_mask;
        static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
-       const unsigned int gpio_reg_size = 8;
-       unsigned int bits_offset;
-       size_t word_index;
-       unsigned int word_offset;
-       unsigned long word_mask;
-       const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+       unsigned int port_addr;
        unsigned long port_state;
 
        /* clear bits array to a clean slate */
        bitmap_zero(bits, chip->ngpio);
 
-       /* get bits are evaluated a gpio port register at a time */
-       for (i = 0; i < ARRAY_SIZE(ports); i++) {
-               /* gpio offset in bits array */
-               bits_offset = i * gpio_reg_size;
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               port_addr = idi48gpio->base + ports[offset / 8];
+               port_state = inb(port_addr) & gpio_mask;
 
-               /* word index for bits array */
-               word_index = BIT_WORD(bits_offset);
-
-               /* gpio offset within current word of bits array */
-               word_offset = bits_offset % BITS_PER_LONG;
-
-               /* mask of get bits for current gpio within current word */
-               word_mask = mask[word_index] & (port_mask << word_offset);
-               if (!word_mask) {
-                       /* no get bits in this port so skip to next one */
-                       continue;
-               }
-
-               /* read bits from current gpio port */
-               port_state = inb(idi48gpio->base + ports[i]);
-
-               /* store acquired bits at respective bits array offset */
-               bits[word_index] |= (port_state << word_offset) & word_mask;
+               bitmap_set_value8(bits, port_state, offset);
        }
 
        return 0;
index e81307f..05637d5 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com>
  */
 
+#include <linux/bitops.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <linux/module.h>
@@ -72,20 +73,18 @@ static void gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask,
                                    unsigned long *bits)
 {
        struct gen_74x164_chip *chip = gpiochip_get_data(gc);
-       unsigned int i, idx, shift;
-       u8 bank, bankmask;
+       unsigned long offset;
+       unsigned long bankmask;
+       size_t bank;
+       unsigned long bitmask;
 
        mutex_lock(&chip->lock);
-       for (i = 0, bank = chip->registers - 1; i < chip->registers;
-            i++, bank--) {
-               idx = i / sizeof(*mask);
-               shift = i % sizeof(*mask) * BITS_PER_BYTE;
-               bankmask = mask[idx] >> shift;
-               if (!bankmask)
-                       continue;
+       for_each_set_clump8(offset, bankmask, mask, chip->registers * 8) {
+               bank = chip->registers - 1 - offset / 8;
+               bitmask = bitmap_get_value8(bits, offset) & bankmask;
 
                chip->buffer[bank] &= ~bankmask;
-               chip->buffer[bank] |= bankmask & (bits[idx] >> shift);
+               chip->buffer[bank] |= bitmask;
        }
        __gen_74x164_write_config(chip);
        mutex_unlock(&chip->lock);
index c22d6f9..b89b8c5 100644 (file)
@@ -167,46 +167,25 @@ static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset)
        return !!(port_state & mask);
 }
 
+static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
+
 static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
        unsigned long *bits)
 {
        struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
-       size_t i;
-       static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
-       const unsigned int gpio_reg_size = 8;
-       unsigned int bits_offset;
-       size_t word_index;
-       unsigned int word_offset;
-       unsigned long word_mask;
-       const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+       unsigned long offset;
+       unsigned long gpio_mask;
+       unsigned int port_addr;
        unsigned long port_state;
 
        /* clear bits array to a clean slate */
        bitmap_zero(bits, chip->ngpio);
 
-       /* get bits are evaluated a gpio port register at a time */
-       for (i = 0; i < ARRAY_SIZE(ports); i++) {
-               /* gpio offset in bits array */
-               bits_offset = i * gpio_reg_size;
-
-               /* word index for bits array */
-               word_index = BIT_WORD(bits_offset);
-
-               /* gpio offset within current word of bits array */
-               word_offset = bits_offset % BITS_PER_LONG;
-
-               /* mask of get bits for current gpio within current word */
-               word_mask = mask[word_index] & (port_mask << word_offset);
-               if (!word_mask) {
-                       /* no get bits in this port so skip to next one */
-                       continue;
-               }
-
-               /* read bits from current gpio port */
-               port_state = inb(gpiommgpio->base + ports[i]);
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               port_addr = gpiommgpio->base + ports[offset / 8];
+               port_state = inb(port_addr) & gpio_mask;
 
-               /* store acquired bits at respective bits array offset */
-               bits[word_index] |= (port_state << word_offset) & word_mask;
+               bitmap_set_value8(bits, port_state, offset);
        }
 
        return 0;
@@ -237,37 +216,27 @@ static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
-       unsigned int i;
-       const unsigned int gpio_reg_size = 8;
-       unsigned int port;
-       unsigned int out_port;
-       unsigned int bitmask;
+       unsigned long offset;
+       unsigned long gpio_mask;
+       size_t index;
+       unsigned int port_addr;
+       unsigned long bitmask;
        unsigned long flags;
 
-       /* set bits are evaluated a gpio register size at a time */
-       for (i = 0; i < chip->ngpio; i += gpio_reg_size) {
-               /* no more set bits in this mask word; skip to the next word */
-               if (!mask[BIT_WORD(i)]) {
-                       i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size;
-                       continue;
-               }
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               index = offset / 8;
+               port_addr = gpiommgpio->base + ports[index];
 
-               port = i / gpio_reg_size;
-               out_port = (port > 2) ? port + 1 : port;
-               bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
+               bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
 
                spin_lock_irqsave(&gpiommgpio->lock, flags);
 
                /* update output state data and set device gpio register */
-               gpiommgpio->out_state[port] &= ~mask[BIT_WORD(i)];
-               gpiommgpio->out_state[port] |= bitmask;
-               outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port);
+               gpiommgpio->out_state[index] &= ~gpio_mask;
+               gpiommgpio->out_state[index] |= bitmask;
+               outb(gpiommgpio->out_state[index], port_addr);
 
                spin_unlock_irqrestore(&gpiommgpio->lock, flags);
-
-               /* prepare for next gpio register set */
-               mask[BIT_WORD(i)] >>= gpio_reg_size;
-               bits[BIT_WORD(i)] >>= gpio_reg_size;
        }
 }
 
index 0696d5a..310d1a2 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/bitmap.h>
+#include <linux/bitops.h>
 #include <linux/crc8.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
@@ -232,16 +233,20 @@ static int max3191x_get_multiple(struct gpio_chip *gpio, unsigned long *mask,
                                 unsigned long *bits)
 {
        struct max3191x_chip *max3191x = gpiochip_get_data(gpio);
-       int ret, bit = 0, wordlen = max3191x_wordlen(max3191x);
+       const unsigned int wordlen = max3191x_wordlen(max3191x);
+       int ret;
+       unsigned long bit;
+       unsigned long gpio_mask;
+       unsigned long in;
 
        mutex_lock(&max3191x->lock);
        ret = max3191x_readout_locked(max3191x);
        if (ret)
                goto out_unlock;
 
-       while ((bit = find_next_bit(mask, gpio->ngpio, bit)) != gpio->ngpio) {
+       bitmap_zero(bits, gpio->ngpio);
+       for_each_set_clump8(bit, gpio_mask, mask, gpio->ngpio) {
                unsigned int chipnum = bit / MAX3191X_NGPIO;
-               unsigned long in, shift, index;
 
                if (max3191x_chip_is_faulting(max3191x, chipnum)) {
                        ret = -EIO;
@@ -249,12 +254,8 @@ static int max3191x_get_multiple(struct gpio_chip *gpio, unsigned long *mask,
                }
 
                in = ((u8 *)max3191x->xfer.rx_buf)[chipnum * wordlen];
-               shift = round_down(bit % BITS_PER_LONG, MAX3191X_NGPIO);
-               index = bit / BITS_PER_LONG;
-               bits[index] &= ~(mask[index] & (0xff << shift));
-               bits[index] |= mask[index] & (in << shift); /* copy bits */
-
-               bit = (chipnum + 1) * MAX3191X_NGPIO; /* go to next chip */
+               in &= gpio_mask;
+               bitmap_set_value8(bits, in, bit);
        }
 
 out_unlock:
index 82122c3..6652bee 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/acpi.h>
-#include <linux/bits.h>
+#include <linux/bitmap.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
@@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
 
 #define MAX_BANK 5
 #define BANK_SZ 8
+#define MAX_LINE       (MAX_BANK * BANK_SZ)
 
 #define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ)
 
@@ -146,10 +147,10 @@ struct pca953x_chip {
 
 #ifdef CONFIG_GPIO_PCA953X_IRQ
        struct mutex irq_lock;
-       u8 irq_mask[MAX_BANK];
-       u8 irq_stat[MAX_BANK];
-       u8 irq_trig_raise[MAX_BANK];
-       u8 irq_trig_fall[MAX_BANK];
+       DECLARE_BITMAP(irq_mask, MAX_LINE);
+       DECLARE_BITMAP(irq_stat, MAX_LINE);
+       DECLARE_BITMAP(irq_trig_raise, MAX_LINE);
+       DECLARE_BITMAP(irq_trig_fall, MAX_LINE);
        struct irq_chip irq_chip;
 #endif
        atomic_t wakeup_path;
@@ -333,12 +334,16 @@ static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off,
        return regaddr;
 }
 
-static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)
+static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
 {
        u8 regaddr = pca953x_recalc_addr(chip, reg, 0, true, true);
-       int ret;
+       u8 value[MAX_BANK];
+       int i, ret;
+
+       for (i = 0; i < NBANK(chip); i++)
+               value[i] = bitmap_get_value8(val, i * BANK_SZ);
 
-       ret = regmap_bulk_write(chip->regmap, regaddr, val, NBANK(chip));
+       ret = regmap_bulk_write(chip->regmap, regaddr, value, NBANK(chip));
        if (ret < 0) {
                dev_err(&chip->client->dev, "failed writing register\n");
                return ret;
@@ -347,17 +352,21 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)
        return 0;
 }
 
-static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)
+static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
 {
        u8 regaddr = pca953x_recalc_addr(chip, reg, 0, false, true);
-       int ret;
+       u8 value[MAX_BANK];
+       int i, ret;
 
-       ret = regmap_bulk_read(chip->regmap, regaddr, val, NBANK(chip));
+       ret = regmap_bulk_read(chip->regmap, regaddr, value, NBANK(chip));
        if (ret < 0) {
                dev_err(&chip->client->dev, "failed reading register\n");
                return ret;
        }
 
+       for (i = 0; i < NBANK(chip); i++)
+               bitmap_set_value8(val, value[i], i * BANK_SZ);
+
        return 0;
 }
 
@@ -412,7 +421,9 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
        ret = regmap_read(chip->regmap, inreg, &reg_val);
        mutex_unlock(&chip->i2c_lock);
        if (ret < 0) {
-               /* NOTE:  diagnostic already emitted; that's all we should
+               /*
+                * NOTE:
+                * diagnostic already emitted; that's all we should
                 * do unless gpio_*_value_cansleep() calls become different
                 * from their nonsleeping siblings (and report faults).
                 */
@@ -459,9 +470,7 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
                                      unsigned long *mask, unsigned long *bits)
 {
        struct pca953x_chip *chip = gpiochip_get_data(gc);
-       unsigned int bank_mask, bank_val;
-       int bank;
-       u8 reg_val[MAX_BANK];
+       DECLARE_BITMAP(reg_val, MAX_LINE);
        int ret;
 
        mutex_lock(&chip->i2c_lock);
@@ -469,16 +478,7 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
        if (ret)
                goto exit;
 
-       for (bank = 0; bank < NBANK(chip); bank++) {
-               bank_mask = mask[bank / sizeof(*mask)] >>
-                          ((bank % sizeof(*mask)) * 8);
-               if (bank_mask) {
-                       bank_val = bits[bank / sizeof(*bits)] >>
-                                 ((bank % sizeof(*bits)) * 8);
-                       bank_val &= bank_mask;
-                       reg_val[bank] = (reg_val[bank] & ~bank_mask) | bank_val;
-               }
-       }
+       bitmap_replace(reg_val, reg_val, bits, mask, gc->ngpio);
 
        pca953x_write_regs(chip, chip->regs->output, reg_val);
 exit:
@@ -605,10 +605,9 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct pca953x_chip *chip = gpiochip_get_data(gc);
-       u8 new_irqs;
-       int level, i;
-       u8 invert_irq_mask[MAX_BANK];
-       u8 reg_direction[MAX_BANK];
+       DECLARE_BITMAP(irq_mask, MAX_LINE);
+       DECLARE_BITMAP(reg_direction, MAX_LINE);
+       int level;
 
        pca953x_read_regs(chip, chip->regs->direction, reg_direction);
 
@@ -616,25 +615,18 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
                /* Enable latch on interrupt-enabled inputs */
                pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask);
 
-               for (i = 0; i < NBANK(chip); i++)
-                       invert_irq_mask[i] = ~chip->irq_mask[i];
+               bitmap_complement(irq_mask, chip->irq_mask, gc->ngpio);
 
                /* Unmask enabled interrupts */
-               pca953x_write_regs(chip, PCAL953X_INT_MASK, invert_irq_mask);
+               pca953x_write_regs(chip, PCAL953X_INT_MASK, irq_mask);
        }
 
+       bitmap_or(irq_mask, chip->irq_trig_fall, chip->irq_trig_raise, gc->ngpio);
+       bitmap_and(irq_mask, irq_mask, reg_direction, gc->ngpio);
+
        /* Look for any newly setup interrupt */
-       for (i = 0; i < NBANK(chip); i++) {
-               new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i];
-               new_irqs &= reg_direction[i];
-
-               while (new_irqs) {
-                       level = __ffs(new_irqs);
-                       pca953x_gpio_direction_input(&chip->gpio_chip,
-                                                       level + (BANK_SZ * i));
-                       new_irqs &= ~(1 << level);
-               }
-       }
+       for_each_set_bit(level, irq_mask, gc->ngpio)
+               pca953x_gpio_direction_input(&chip->gpio_chip, level);
 
        mutex_unlock(&chip->irq_lock);
 }
@@ -675,15 +667,15 @@ static void pca953x_irq_shutdown(struct irq_data *d)
        chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask;
 }
 
-static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
+static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending)
 {
-       u8 cur_stat[MAX_BANK];
-       u8 old_stat[MAX_BANK];
-       bool pending_seen = false;
-       bool trigger_seen = false;
-       u8 trigger[MAX_BANK];
-       u8 reg_direction[MAX_BANK];
-       int ret, i;
+       struct gpio_chip *gc = &chip->gpio_chip;
+       DECLARE_BITMAP(reg_direction, MAX_LINE);
+       DECLARE_BITMAP(old_stat, MAX_LINE);
+       DECLARE_BITMAP(cur_stat, MAX_LINE);
+       DECLARE_BITMAP(new_stat, MAX_LINE);
+       DECLARE_BITMAP(trigger, MAX_LINE);
+       int ret;
 
        if (chip->driver_data & PCA_PCAL) {
                /* Read the current interrupt status from the device */
@@ -692,20 +684,16 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
                        return false;
 
                /* Check latched inputs and clear interrupt status */
-               ret = pca953x_read_regs(chip, PCA953X_INPUT, cur_stat);
+               ret = pca953x_read_regs(chip, chip->regs->input, cur_stat);
                if (ret)
                        return false;
 
-               for (i = 0; i < NBANK(chip); i++) {
-                       /* Apply filter for rising/falling edge selection */
-                       pending[i] = (~cur_stat[i] & chip->irq_trig_fall[i]) |
-                               (cur_stat[i] & chip->irq_trig_raise[i]);
-                       pending[i] &= trigger[i];
-                       if (pending[i])
-                               pending_seen = true;
-               }
+               /* Apply filter for rising/falling edge selection */
+               bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, cur_stat, gc->ngpio);
+
+               bitmap_and(pending, new_stat, trigger, gc->ngpio);
 
-               return pending_seen;
+               return !bitmap_empty(pending, gc->ngpio);
        }
 
        ret = pca953x_read_regs(chip, chip->regs->input, cur_stat);
@@ -714,64 +702,49 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
 
        /* Remove output pins from the equation */
        pca953x_read_regs(chip, chip->regs->direction, reg_direction);
-       for (i = 0; i < NBANK(chip); i++)
-               cur_stat[i] &= reg_direction[i];
 
-       memcpy(old_stat, chip->irq_stat, NBANK(chip));
+       bitmap_copy(old_stat, chip->irq_stat, gc->ngpio);
 
-       for (i = 0; i < NBANK(chip); i++) {
-               trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i];
-               if (trigger[i])
-                       trigger_seen = true;
-       }
+       bitmap_and(new_stat, cur_stat, reg_direction, gc->ngpio);
+       bitmap_xor(cur_stat, new_stat, old_stat, gc->ngpio);
+       bitmap_and(trigger, cur_stat, chip->irq_mask, gc->ngpio);
 
-       if (!trigger_seen)
+       if (bitmap_empty(trigger, gc->ngpio))
                return false;
 
-       memcpy(chip->irq_stat, cur_stat, NBANK(chip));
+       bitmap_copy(chip->irq_stat, new_stat, gc->ngpio);
 
-       for (i = 0; i < NBANK(chip); i++) {
-               pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) |
-                       (cur_stat[i] & chip->irq_trig_raise[i]);
-               pending[i] &= trigger[i];
-               if (pending[i])
-                       pending_seen = true;
-       }
+       bitmap_and(cur_stat, chip->irq_trig_fall, old_stat, gc->ngpio);
+       bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio);
+       bitmap_or(new_stat, old_stat, cur_stat, gc->ngpio);
+       bitmap_and(pending, new_stat, trigger, gc->ngpio);
 
-       return pending_seen;
+       return !bitmap_empty(pending, gc->ngpio);
 }
 
 static irqreturn_t pca953x_irq_handler(int irq, void *devid)
 {
        struct pca953x_chip *chip = devid;
-       u8 pending[MAX_BANK];
-       u8 level;
-       unsigned nhandled = 0;
-       int i;
+       struct gpio_chip *gc = &chip->gpio_chip;
+       DECLARE_BITMAP(pending, MAX_LINE);
+       int level;
 
        if (!pca953x_irq_pending(chip, pending))
                return IRQ_NONE;
 
-       for (i = 0; i < NBANK(chip); i++) {
-               while (pending[i]) {
-                       level = __ffs(pending[i]);
-                       handle_nested_irq(irq_find_mapping(chip->gpio_chip.irq.domain,
-                                                       level + (BANK_SZ * i)));
-                       pending[i] &= ~(1 << level);
-                       nhandled++;
-               }
-       }
+       for_each_set_bit(level, pending, gc->ngpio)
+               handle_nested_irq(irq_find_mapping(gc->irq.domain, level));
 
-       return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE;
+       return IRQ_HANDLED;
 }
 
-static int pca953x_irq_setup(struct pca953x_chip *chip,
-                            int irq_base)
+static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)
 {
        struct i2c_client *client = chip->client;
        struct irq_chip *irq_chip = &chip->irq_chip;
-       u8 reg_direction[MAX_BANK];
-       int ret, i;
+       DECLARE_BITMAP(reg_direction, MAX_LINE);
+       DECLARE_BITMAP(irq_stat, MAX_LINE);
+       int ret;
 
        if (!client->irq)
                return 0;
@@ -782,7 +755,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
        if (!(chip->driver_data & PCA_INT))
                return 0;
 
-       ret = pca953x_read_regs(chip, chip->regs->input, chip->irq_stat);
+       ret = pca953x_read_regs(chip, chip->regs->input, irq_stat);
        if (ret)
                return ret;
 
@@ -792,8 +765,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
         * this purpose.
         */
        pca953x_read_regs(chip, chip->regs->direction, reg_direction);
-       for (i = 0; i < NBANK(chip); i++)
-               chip->irq_stat[i] &= reg_direction[i];
+       bitmap_and(chip->irq_stat, irq_stat, reg_direction, chip->gpio_chip.ngpio);
        mutex_init(&chip->irq_lock);
 
        ret = devm_request_threaded_irq(&client->dev, client->irq,
@@ -816,9 +788,9 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
        irq_chip->irq_set_type = pca953x_irq_set_type;
        irq_chip->irq_shutdown = pca953x_irq_shutdown;
 
-       ret =  gpiochip_irqchip_add_nested(&chip->gpio_chip, irq_chip,
-                                          irq_base, handle_simple_irq,
-                                          IRQ_TYPE_NONE);
+       ret = gpiochip_irqchip_add_nested(&chip->gpio_chip, irq_chip,
+                                         irq_base, handle_simple_irq,
+                                         IRQ_TYPE_NONE);
        if (ret) {
                dev_err(&client->dev,
                        "could not connect irqchip to gpiochip\n");
@@ -845,8 +817,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 
 static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
 {
+       DECLARE_BITMAP(val, MAX_LINE);
        int ret;
-       u8 val[MAX_BANK];
 
        ret = regcache_sync_region(chip->regmap, chip->regs->output,
                                   chip->regs->output + NBANK(chip));
@@ -860,9 +832,9 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
 
        /* set platform specific polarity inversion */
        if (invert)
-               memset(val, 0xFF, NBANK(chip));
+               bitmap_fill(val, MAX_LINE);
        else
-               memset(val, 0, NBANK(chip));
+               bitmap_zero(val, MAX_LINE);
 
        ret = pca953x_write_regs(chip, chip->regs->invert, val);
 out:
@@ -871,8 +843,8 @@ out:
 
 static int device_pca957x_init(struct pca953x_chip *chip, u32 invert)
 {
+       DECLARE_BITMAP(val, MAX_LINE);
        int ret;
-       u8 val[MAX_BANK];
 
        ret = device_pca95xx_init(chip, invert);
        if (ret)
@@ -892,7 +864,7 @@ out:
 static const struct of_device_id pca953x_dt_ids[];
 
 static int pca953x_probe(struct i2c_client *client,
-                                  const struct i2c_device_id *i2c_id)
+                        const struct i2c_device_id *i2c_id)
 {
        struct pca953x_platform_data *pdata;
        struct pca953x_chip *chip;
@@ -901,8 +873,7 @@ static int pca953x_probe(struct i2c_client *client,
        u32 invert = 0;
        struct regulator *reg;
 
-       chip = devm_kzalloc(&client->dev,
-                       sizeof(struct pca953x_chip), GFP_KERNEL);
+       chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
        if (chip == NULL)
                return -ENOMEM;
 
@@ -1016,7 +987,7 @@ static int pca953x_probe(struct i2c_client *client,
 
        if (pdata && pdata->setup) {
                ret = pdata->setup(client, chip->gpio_chip.base,
-                               chip->gpio_chip.ngpio, pdata->context);
+                                  chip->gpio_chip.ngpio, pdata->context);
                if (ret < 0)
                        dev_warn(&client->dev, "setup failed, %d\n", ret);
        }
@@ -1036,7 +1007,7 @@ static int pca953x_remove(struct i2c_client *client)
 
        if (pdata && pdata->teardown) {
                ret = pdata->teardown(client, chip->gpio_chip.base,
-                               chip->gpio_chip.ngpio, pdata->context);
+                                     chip->gpio_chip.ngpio, pdata->context);
                if (ret < 0)
                        dev_err(&client->dev, "teardown failed, %d\n", ret);
        } else {
index df51dd0..638d665 100644 (file)
@@ -100,45 +100,23 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
-       size_t i;
-       const unsigned int gpio_reg_size = 8;
-       unsigned int bits_offset;
-       size_t word_index;
-       unsigned int word_offset;
-       unsigned long word_mask;
-       const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
-       unsigned long port_state;
+       unsigned long offset;
+       unsigned long gpio_mask;
        void __iomem *ports[] = {
                &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
                &idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15,
        };
+       void __iomem *port_addr;
+       unsigned long port_state;
 
        /* clear bits array to a clean slate */
        bitmap_zero(bits, chip->ngpio);
 
-       /* get bits are evaluated a gpio port register at a time */
-       for (i = 0; i < ARRAY_SIZE(ports); i++) {
-               /* gpio offset in bits array */
-               bits_offset = i * gpio_reg_size;
-
-               /* word index for bits array */
-               word_index = BIT_WORD(bits_offset);
-
-               /* gpio offset within current word of bits array */
-               word_offset = bits_offset % BITS_PER_LONG;
-
-               /* mask of get bits for current gpio within current word */
-               word_mask = mask[word_index] & (port_mask << word_offset);
-               if (!word_mask) {
-                       /* no get bits in this port so skip to next one */
-                       continue;
-               }
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               port_addr = ports[offset / 8];
+               port_state = ioread8(port_addr) & gpio_mask;
 
-               /* read bits from current gpio port */
-               port_state = ioread8(ports[i]);
-
-               /* store acquired bits at respective bits array offset */
-               bits[word_index] |= (port_state << word_offset) & word_mask;
+               bitmap_set_value8(bits, port_state, offset);
        }
 
        return 0;
@@ -178,30 +156,31 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
+       unsigned long offset;
+       unsigned long gpio_mask;
+       void __iomem *ports[] = {
+               &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
+       };
+       size_t index;
+       void __iomem *port_addr;
+       unsigned long bitmask;
        unsigned long flags;
-       unsigned int out_state;
+       unsigned long out_state;
 
-       raw_spin_lock_irqsave(&idio16gpio->lock, flags);
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               index = offset / 8;
+               port_addr = ports[index];
 
-       /* process output lines 0-7 */
-       if (*mask & 0xFF) {
-               out_state = ioread8(&idio16gpio->reg->out0_7) & ~*mask;
-               out_state |= *mask & *bits;
-               iowrite8(out_state, &idio16gpio->reg->out0_7);
-       }
+               bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
+
+               raw_spin_lock_irqsave(&idio16gpio->lock, flags);
 
-       /* shift to next output line word */
-       *mask >>= 8;
+               out_state = ioread8(port_addr) & ~gpio_mask;
+               out_state |= bitmask;
+               iowrite8(out_state, port_addr);
 
-       /* process output lines 8-15 */
-       if (*mask & 0xFF) {
-               *bits >>= 8;
-               out_state = ioread8(&idio16gpio->reg->out8_15) & ~*mask;
-               out_state |= *mask & *bits;
-               iowrite8(out_state, &idio16gpio->reg->out8_15);
+               raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
        }
-
-       raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
 }
 
 static void idio_16_irq_ack(struct irq_data *data)
index 44c1e4f..1d47579 100644 (file)
@@ -201,52 +201,34 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
-       size_t i;
-       const unsigned int gpio_reg_size = 8;
-       unsigned int bits_offset;
-       size_t word_index;
-       unsigned int word_offset;
-       unsigned long word_mask;
-       const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
-       unsigned long port_state;
+       unsigned long offset;
+       unsigned long gpio_mask;
        void __iomem *ports[] = {
                &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
                &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
                &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
        };
+       size_t index;
+       unsigned long port_state;
        const unsigned long out_mode_mask = BIT(1);
 
        /* clear bits array to a clean slate */
        bitmap_zero(bits, chip->ngpio);
 
-       /* get bits are evaluated a gpio port register at a time */
-       for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) {
-               /* gpio offset in bits array */
-               bits_offset = i * gpio_reg_size;
-
-               /* word index for bits array */
-               word_index = BIT_WORD(bits_offset);
-
-               /* gpio offset within current word of bits array */
-               word_offset = bits_offset % BITS_PER_LONG;
-
-               /* mask of get bits for current gpio within current word */
-               word_mask = mask[word_index] & (port_mask << word_offset);
-               if (!word_mask) {
-                       /* no get bits in this port so skip to next one */
-                       continue;
-               }
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               index = offset / 8;
 
                /* read bits from current gpio port (port 6 is TTL GPIO) */
-               if (i < 6)
-                       port_state = ioread8(ports[i]);
+               if (index < 6)
+                       port_state = ioread8(ports[index]);
                else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
                        port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
                else
                        port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
 
-               /* store acquired bits at respective bits array offset */
-               bits[word_index] |= (port_state << word_offset) & word_mask;
+               port_state &= gpio_mask;
+
+               bitmap_set_value8(bits, port_state, offset);
        }
 
        return 0;
@@ -297,59 +279,48 @@ static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
-       size_t i;
-       unsigned long bits_offset;
+       unsigned long offset;
        unsigned long gpio_mask;
-       const unsigned int gpio_reg_size = 8;
-       const unsigned long port_mask = GENMASK(gpio_reg_size, 0);
-       unsigned long flags;
-       unsigned int out_state;
        void __iomem *ports[] = {
                &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
                &idio24gpio->reg->out16_23
        };
+       size_t index;
+       unsigned long bitmask;
+       unsigned long flags;
+       unsigned long out_state;
        const unsigned long out_mode_mask = BIT(1);
-       const unsigned int ttl_offset = 48;
-       const size_t ttl_i = BIT_WORD(ttl_offset);
-       const unsigned int word_offset = ttl_offset % BITS_PER_LONG;
-       const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask;
-       const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask;
-
-       /* set bits are processed a gpio port register at a time */
-       for (i = 0; i < ARRAY_SIZE(ports); i++) {
-               /* gpio offset in bits array */
-               bits_offset = i * gpio_reg_size;
-
-               /* check if any set bits for current port */
-               gpio_mask = (*mask >> bits_offset) & port_mask;
-               if (!gpio_mask) {
-                       /* no set bits for this port so move on to next port */
-                       continue;
-               }
 
-               raw_spin_lock_irqsave(&idio24gpio->lock, flags);
+       for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
+               index = offset / 8;
 
-               /* process output lines */
-               out_state = ioread8(ports[i]) & ~gpio_mask;
-               out_state |= (*bits >> bits_offset) & gpio_mask;
-               iowrite8(out_state, ports[i]);
+               bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
 
-               raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
-       }
+               raw_spin_lock_irqsave(&idio24gpio->lock, flags);
 
-       /* check if setting TTL lines and if they are in output mode */
-       if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
-               return;
+               /* read bits from current gpio port (port 6 is TTL GPIO) */
+               if (index < 6) {
+                       out_state = ioread8(ports[index]);
+               } else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) {
+                       out_state = ioread8(&idio24gpio->reg->ttl_out0_7);
+               } else {
+                       /* skip TTL GPIO if set for input */
+                       raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
+                       continue;
+               }
 
-       /* handle TTL output */
-       raw_spin_lock_irqsave(&idio24gpio->lock, flags);
+               /* set requested bit states */
+               out_state &= ~gpio_mask;
+               out_state |= bitmask;
 
-       /* process output lines */
-       out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask;
-       out_state |= ttl_bits;
-       iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
+               /* write bits for current gpio port (port 6 is TTL GPIO) */
+               if (index < 6)
+                       iowrite8(out_state, ports[index]);
+               else
+                       iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
 
-       raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
+               raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
+       }
 }
 
 static void idio_24_irq_ack(struct irq_data *data)
index 1331b2a..6698fea 100644 (file)
@@ -96,16 +96,16 @@ static int pisosr_gpio_get_multiple(struct gpio_chip *chip,
                                    unsigned long *mask, unsigned long *bits)
 {
        struct pisosr_gpio *gpio = gpiochip_get_data(chip);
-       unsigned int nbytes = DIV_ROUND_UP(chip->ngpio, 8);
-       unsigned int i, j;
+       unsigned long offset;
+       unsigned long gpio_mask;
+       unsigned long buffer_state;
 
        pisosr_gpio_refresh(gpio);
 
        bitmap_zero(bits, chip->ngpio);
-       for (i = 0; i < nbytes; i++) {
-               j = i / sizeof(unsigned long);
-               bits[j] |= ((unsigned long) gpio->buffer[i])
-                          << (8 * (i % sizeof(unsigned long)));
+       for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
+               buffer_state = gpio->buffer[offset / 8] & gpio_mask;
+               bitmap_set_value8(bits, buffer_state, offset);
        }
 
        return 0;
index bd203e8..7ec9749 100644 (file)
@@ -15,9 +15,6 @@
 #include <linux/spinlock.h>
 #include <dt-bindings/gpio/uniphier-gpio.h>
 
-#define UNIPHIER_GPIO_BANK_MASK                \
-                               GENMASK((UNIPHIER_GPIO_LINES_PER_BANK) - 1, 0)
-
 #define UNIPHIER_GPIO_IRQ_MAX_NUM      24
 
 #define UNIPHIER_GPIO_PORT_DATA                0x0     /* data */
@@ -150,15 +147,11 @@ static void uniphier_gpio_set(struct gpio_chip *chip,
 static void uniphier_gpio_set_multiple(struct gpio_chip *chip,
                                       unsigned long *mask, unsigned long *bits)
 {
-       unsigned int bank, shift, bank_mask, bank_bits;
-       int i;
+       unsigned long i, bank, bank_mask, bank_bits;
 
-       for (i = 0; i < chip->ngpio; i += UNIPHIER_GPIO_LINES_PER_BANK) {
+       for_each_set_clump8(i, bank_mask, mask, chip->ngpio) {
                bank = i / UNIPHIER_GPIO_LINES_PER_BANK;
-               shift = i % BITS_PER_LONG;
-               bank_mask = (mask[BIT_WORD(i)] >> shift) &
-                                               UNIPHIER_GPIO_BANK_MASK;
-               bank_bits = bits[BIT_WORD(i)] >> shift;
+               bank_bits = bitmap_get_value8(bits, i);
 
                uniphier_gpio_bank_write(chip, bank, UNIPHIER_GPIO_PORT_DATA,
                                         bank_mask, bank_bits);
index fe456be..cb510df 100644 (file)
@@ -129,42 +129,19 @@ static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
-       const unsigned int gpio_reg_size = 8;
-       size_t i;
-       const size_t num_ports = chip->ngpio / gpio_reg_size;
-       unsigned int bits_offset;
-       size_t word_index;
-       unsigned int word_offset;
-       unsigned long word_mask;
-       const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+       unsigned long offset;
+       unsigned long gpio_mask;
+       unsigned int port_addr;
        unsigned long port_state;
 
        /* clear bits array to a clean slate */
        bitmap_zero(bits, chip->ngpio);
 
-       /* get bits are evaluated a gpio port register at a time */
-       for (i = 0; i < num_ports; i++) {
-               /* gpio offset in bits array */
-               bits_offset = i * gpio_reg_size;
+       for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
+               port_addr = ws16c48gpio->base + offset / 8;
+               port_state = inb(port_addr) & gpio_mask;
 
-               /* word index for bits array */
-               word_index = BIT_WORD(bits_offset);
-
-               /* gpio offset within current word of bits array */
-               word_offset = bits_offset % BITS_PER_LONG;
-
-               /* mask of get bits for current gpio within current word */
-               word_mask = mask[word_index] & (port_mask << word_offset);
-               if (!word_mask) {
-                       /* no get bits in this port so skip to next one */
-                       continue;
-               }
-
-               /* read bits from current gpio port */
-               port_state = inb(ws16c48gpio->base + i);
-
-               /* store acquired bits at respective bits array offset */
-               bits[word_index] |= (port_state << word_offset) & word_mask;
+               bitmap_set_value8(bits, port_state, offset);
        }
 
        return 0;
@@ -198,39 +175,29 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
        unsigned long *mask, unsigned long *bits)
 {
        struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
-       unsigned int i;
-       const unsigned int gpio_reg_size = 8;
-       unsigned int port;
-       unsigned int iomask;
-       unsigned int bitmask;
+       unsigned long offset;
+       unsigned long gpio_mask;
+       size_t index;
+       unsigned int port_addr;
+       unsigned long bitmask;
        unsigned long flags;
 
-       /* set bits are evaluated a gpio register size at a time */
-       for (i = 0; i < chip->ngpio; i += gpio_reg_size) {
-               /* no more set bits in this mask word; skip to the next word */
-               if (!mask[BIT_WORD(i)]) {
-                       i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size;
-                       continue;
-               }
-
-               port = i / gpio_reg_size;
+       for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
+               index = offset / 8;
+               port_addr = ws16c48gpio->base + index;
 
                /* mask out GPIO configured for input */
-               iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port];
-               bitmask = iomask & bits[BIT_WORD(i)];
+               gpio_mask &= ~ws16c48gpio->io_state[index];
+               bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
 
                raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
 
                /* update output state data and set device gpio register */
-               ws16c48gpio->out_state[port] &= ~iomask;
-               ws16c48gpio->out_state[port] |= bitmask;
-               outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
+               ws16c48gpio->out_state[index] &= ~gpio_mask;
+               ws16c48gpio->out_state[index] |= bitmask;
+               outb(ws16c48gpio->out_state[index], port_addr);
 
                raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
-
-               /* prepare for next gpio register set */
-               mask[BIT_WORD(i)] >>= gpio_reg_size;
-               bits[BIT_WORD(i)] >>= gpio_reg_size;
        }
 }
 
index 1168351..bfdadc3 100644 (file)
@@ -95,6 +95,7 @@ config DRM_KMS_FB_HELPER
 
 config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
         bool "Enable refcount backtrace history in the DP MST helpers"
+       depends on STACKTRACE_SUPPORT
         select STACKDEPOT
         depends on DRM_KMS_HELPER
         depends on DEBUG_KERNEL
index d968c24..0d12ebf 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: MIT
 menu "ACP (Audio CoProcessor) Configuration"
 
 config DRM_AMD_ACP
index 2e98c01..9375e7f 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: MIT
 config DRM_AMDGPU_SI
        bool "Enable amdgpu support for SI parts"
        depends on DRM_AMDGPU
index 7d35b5b..888209e 100644 (file)
@@ -105,11 +105,24 @@ void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
                (kfd_mem_limit.max_ttm_mem_limit >> 20));
 }
 
+/* Estimate page table size needed to represent a given memory size
+ *
+ * With 4KB pages, we need one 8 byte PTE for each 4KB of memory
+ * (factor 512, >> 9). With 2MB pages, we need one 8 byte PTE for 2MB
+ * of memory (factor 256K, >> 18). ROCm user mode tries to optimize
+ * for 2MB pages for TLB efficiency. However, small allocations and
+ * fragmented system memory still need some 4KB pages. We choose a
+ * compromise that should work in most cases without reserving too
+ * much memory for page tables unnecessarily (factor 16K, >> 14).
+ */
+#define ESTIMATE_PT_SIZE(mem_size) ((mem_size) >> 14)
+
 static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
                uint64_t size, u32 domain, bool sg)
 {
+       uint64_t reserved_for_pt =
+               ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
        size_t acc_size, system_mem_needed, ttm_mem_needed, vram_needed;
-       uint64_t reserved_for_pt = amdgpu_amdkfd_total_mem_size >> 9;
        int ret = 0;
 
        acc_size = ttm_bo_dma_acc_size(&adev->mman.bdev, size,
index 2cdaf3b..6614d8a 100644 (file)
@@ -604,11 +604,8 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
                        continue;
                }
 
-               for (i = 0; i < num_entities; i++) {
-                       mutex_lock(&ctx->adev->lock_reset);
+               for (i = 0; i < num_entities; i++)
                        drm_sched_entity_fini(&ctx->entities[0][i].entity);
-                       mutex_unlock(&ctx->adev->lock_reset);
-               }
        }
 }
 
index 2770cba..44be3a4 100644 (file)
@@ -1487,8 +1487,8 @@ out:
                        return ret;
 
                /* Start rlc autoload after psp recieved all the gfx firmware */
-               if (psp->autoload_supported && ucode->ucode_id ==
-                       AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) {
+               if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?
+                   AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) {
                        ret = psp_rlc_autoload(psp);
                        if (ret) {
                                DRM_ERROR("Failed to start rlc autoload\n");
index 7de16c0..2a8e048 100644 (file)
@@ -27,7 +27,8 @@
 #include <linux/bits.h>
 #include "smu_v11_0_i2c.h"
 
-#define EEPROM_I2C_TARGET_ADDR 0xA0
+#define EEPROM_I2C_TARGET_ADDR_ARCTURUS  0xA8
+#define EEPROM_I2C_TARGET_ADDR_VEGA20    0xA0
 
 /*
  * The 2 macros bellow represent the actual size in bytes that
@@ -83,7 +84,7 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control,
 {
        int ret = 0;
        struct i2c_msg msg = {
-                       .addr   = EEPROM_I2C_TARGET_ADDR,
+                       .addr   = 0,
                        .flags  = 0,
                        .len    = EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE,
                        .buf    = buff,
@@ -93,6 +94,8 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control,
        *(uint16_t *)buff = EEPROM_HDR_START;
        __encode_table_header_to_buff(&control->tbl_hdr, buff + EEPROM_ADDRESS_SIZE);
 
+       msg.addr = control->i2c_address;
+
        ret = i2c_transfer(&control->eeprom_accessor, &msg, 1);
        if (ret < 1)
                DRM_ERROR("Failed to write EEPROM table header, ret:%d", ret);
@@ -203,7 +206,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
        unsigned char buff[EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE] = { 0 };
        struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr;
        struct i2c_msg msg = {
-                       .addr   = EEPROM_I2C_TARGET_ADDR,
+                       .addr   = 0,
                        .flags  = I2C_M_RD,
                        .len    = EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE,
                        .buf    = buff,
@@ -213,10 +216,12 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
 
        switch (adev->asic_type) {
        case CHIP_VEGA20:
+               control->i2c_address = EEPROM_I2C_TARGET_ADDR_VEGA20;
                ret = smu_v11_0_i2c_eeprom_control_init(&control->eeprom_accessor);
                break;
 
        case CHIP_ARCTURUS:
+               control->i2c_address = EEPROM_I2C_TARGET_ADDR_ARCTURUS;
                ret = smu_i2c_eeprom_init(&adev->smu, &control->eeprom_accessor);
                break;
 
@@ -229,6 +234,8 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
                return ret;
        }
 
+       msg.addr = control->i2c_address;
+
        /* Read/Create table header from EEPROM address 0 */
        ret = i2c_transfer(&control->eeprom_accessor, &msg, 1);
        if (ret < 1) {
@@ -408,8 +415,8 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
                 * Update bits 16,17 of EEPROM address in I2C address by setting them
                 * to bits 1,2 of Device address byte
                 */
-               msg->addr = EEPROM_I2C_TARGET_ADDR |
-                              ((control->next_addr & EEPROM_ADDR_MSB_MASK) >> 15);
+               msg->addr = control->i2c_address |
+                               ((control->next_addr & EEPROM_ADDR_MSB_MASK) >> 15);
                msg->flags      = write ? 0 : I2C_M_RD;
                msg->len        = EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE;
                msg->buf        = buff;
index 6222699..ca78f81 100644 (file)
@@ -50,6 +50,7 @@ struct amdgpu_ras_eeprom_control {
        struct mutex tbl_mutex;
        bool bus_locked;
        uint32_t tbl_byte_sum;
+       uint16_t i2c_address; // 8-bit represented address
 };
 
 /*
index c8793e6..6373bfb 100644 (file)
@@ -124,13 +124,12 @@ int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws)
  */
 int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
 {
-       volatile u32 *dst_ptr;
        u32 dws;
        int r;
 
        /* allocate clear state block */
        adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev);
-       r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+       r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
                                      AMDGPU_GEM_DOMAIN_VRAM,
                                      &adev->gfx.rlc.clear_state_obj,
                                      &adev->gfx.rlc.clear_state_gpu_addr,
@@ -141,13 +140,6 @@ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
                return r;
        }
 
-       /* set up the cs buffer */
-       dst_ptr = adev->gfx.rlc.cs_ptr;
-       adev->gfx.rlc.funcs->get_csb_buffer(adev, dst_ptr);
-       amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
-       amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-       amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
        return 0;
 }
 
index 7a43993..1befdee 100644 (file)
@@ -1346,10 +1346,13 @@ static int cik_asic_reset(struct amdgpu_device *adev)
 {
        int r;
 
-       if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
+       if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
+               if (!adev->in_suspend)
+                       amdgpu_inc_vram_lost(adev);
                r = smu7_asic_baco_reset(adev);
-       else
+       } else {
                r = cik_asic_pci_config_reset(adev);
+       }
 
        return r;
 }
index 16fbd2b..4043ebc 100644 (file)
@@ -268,23 +268,29 @@ static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,
 {
        u32 tmp;
 
-       /* Put DF on broadcast mode */
-       adev->df_funcs->enable_broadcast_mode(adev, true);
-
-       if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) {
-               tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
-               tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
-               tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY;
-               WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
-       } else {
-               tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
-               tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
-               tmp |= DF_V3_6_MGCG_DISABLE;
-               WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
-       }
+       if (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG) {
+               /* Put DF on broadcast mode */
+               adev->df_funcs->enable_broadcast_mode(adev, true);
+
+               if (enable) {
+                       tmp = RREG32_SOC15(DF, 0,
+                                       mmDF_PIE_AON0_DfGlobalClkGater);
+                       tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
+                       tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY;
+                       WREG32_SOC15(DF, 0,
+                                       mmDF_PIE_AON0_DfGlobalClkGater, tmp);
+               } else {
+                       tmp = RREG32_SOC15(DF, 0,
+                                       mmDF_PIE_AON0_DfGlobalClkGater);
+                       tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
+                       tmp |= DF_V3_6_MGCG_DISABLE;
+                       WREG32_SOC15(DF, 0,
+                                       mmDF_PIE_AON0_DfGlobalClkGater, tmp);
+               }
 
-       /* Exit broadcast mode */
-       adev->df_funcs->enable_broadcast_mode(adev, false);
+               /* Exit broadcast mode */
+               adev->df_funcs->enable_broadcast_mode(adev, false);
+       }
 }
 
 static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev,
index ca5f0e7..ba9e53a 100644 (file)
@@ -117,10 +117,13 @@ static const struct soc15_reg_golden golden_settings_gc_10_1[] =
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CGTT_SCLK_CTRL, 0x10000000, 0x10000100),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL2, 0xffffffff, 0x1402002f),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0xffff9fff, 0x00001188),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x08000009),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_1, 0x00400000, 0x04440000),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000800, 0x00000820),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_SPARE, 0xffffffff, 0xffff3101),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL, 0x001f0000, 0x00070104),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ALU_CLK_CTRL, 0xffffffff, 0xffffffff),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ARB_CONFIG, 0x00000100, 0x00000130),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_LDS_CLK_CTRL, 0xffffffff, 0xffffffff),
@@ -162,10 +165,13 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_1[] =
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CGTT_SCLK_CTRL, 0xffff0fff, 0x10000100),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL2, 0xffffffff, 0x1402002f),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0xffffbfff, 0x00000188),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x08000009),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_1, 0x00400000, 0x04440000),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000800, 0x00000820),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_SPARE, 0xffffffff, 0xffff3101),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL, 0x001f0000, 0x00070105),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ALU_CLK_CTRL, 0xffffffff, 0xffffffff),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ARB_CONFIG, 0x00000133, 0x00000130),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_LDS_CLK_CTRL, 0xffffffff, 0xffffffff),
@@ -690,59 +696,61 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
        adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
        adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
 
-       snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name);
-       err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
-       if (err)
-               goto out;
-       err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
-       rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
-       version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
-       version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
-       if (version_major == 2 && version_minor == 1)
-               adev->gfx.rlc.is_rlc_v2_1 = true;
-
-       adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
-       adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
-       adev->gfx.rlc.save_and_restore_offset =
+       if (!amdgpu_sriov_vf(adev)) {
+               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name);
+               err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
+               if (err)
+                       goto out;
+               err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
+               rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
+               version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
+               version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
+               if (version_major == 2 && version_minor == 1)
+                       adev->gfx.rlc.is_rlc_v2_1 = true;
+
+               adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
+               adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
+               adev->gfx.rlc.save_and_restore_offset =
                        le32_to_cpu(rlc_hdr->save_and_restore_offset);
-       adev->gfx.rlc.clear_state_descriptor_offset =
+               adev->gfx.rlc.clear_state_descriptor_offset =
                        le32_to_cpu(rlc_hdr->clear_state_descriptor_offset);
-       adev->gfx.rlc.avail_scratch_ram_locations =
+               adev->gfx.rlc.avail_scratch_ram_locations =
                        le32_to_cpu(rlc_hdr->avail_scratch_ram_locations);
-       adev->gfx.rlc.reg_restore_list_size =
+               adev->gfx.rlc.reg_restore_list_size =
                        le32_to_cpu(rlc_hdr->reg_restore_list_size);
-       adev->gfx.rlc.reg_list_format_start =
+               adev->gfx.rlc.reg_list_format_start =
                        le32_to_cpu(rlc_hdr->reg_list_format_start);
-       adev->gfx.rlc.reg_list_format_separate_start =
+               adev->gfx.rlc.reg_list_format_separate_start =
                        le32_to_cpu(rlc_hdr->reg_list_format_separate_start);
-       adev->gfx.rlc.starting_offsets_start =
+               adev->gfx.rlc.starting_offsets_start =
                        le32_to_cpu(rlc_hdr->starting_offsets_start);
-       adev->gfx.rlc.reg_list_format_size_bytes =
+               adev->gfx.rlc.reg_list_format_size_bytes =
                        le32_to_cpu(rlc_hdr->reg_list_format_size_bytes);
-       adev->gfx.rlc.reg_list_size_bytes =
+               adev->gfx.rlc.reg_list_size_bytes =
                        le32_to_cpu(rlc_hdr->reg_list_size_bytes);
-       adev->gfx.rlc.register_list_format =
+               adev->gfx.rlc.register_list_format =
                        kmalloc(adev->gfx.rlc.reg_list_format_size_bytes +
-                               adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
-       if (!adev->gfx.rlc.register_list_format) {
-               err = -ENOMEM;
-               goto out;
-       }
+                                       adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
+               if (!adev->gfx.rlc.register_list_format) {
+                       err = -ENOMEM;
+                       goto out;
+               }
 
-       tmp = (unsigned int *)((uintptr_t)rlc_hdr +
-                       le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
-       for (i = 0 ; i < (rlc_hdr->reg_list_format_size_bytes >> 2); i++)
-               adev->gfx.rlc.register_list_format[i] = le32_to_cpu(tmp[i]);
+               tmp = (unsigned int *)((uintptr_t)rlc_hdr +
+                                                          le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
+               for (i = 0 ; i < (rlc_hdr->reg_list_format_size_bytes >> 2); i++)
+                       adev->gfx.rlc.register_list_format[i] = le32_to_cpu(tmp[i]);
 
-       adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
+               adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
 
-       tmp = (unsigned int *)((uintptr_t)rlc_hdr +
-                       le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
-       for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
-               adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
+               tmp = (unsigned int *)((uintptr_t)rlc_hdr +
+                                                          le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
+               for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
+                       adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
 
-       if (adev->gfx.rlc.is_rlc_v2_1)
-               gfx_v10_0_init_rlc_ext_microcode(adev);
+               if (adev->gfx.rlc.is_rlc_v2_1)
+                       gfx_v10_0_init_rlc_ext_microcode(adev);
+       }
 
        snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", chip_name, wks);
        err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
@@ -993,39 +1001,6 @@ static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
        return 0;
 }
 
-static int gfx_v10_0_csb_vram_pin(struct amdgpu_device *adev)
-{
-       int r;
-
-       r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-       if (unlikely(r != 0))
-               return r;
-
-       r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
-                       AMDGPU_GEM_DOMAIN_VRAM);
-       if (!r)
-               adev->gfx.rlc.clear_state_gpu_addr =
-                       amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
-
-       amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
-       return r;
-}
-
-static void gfx_v10_0_csb_vram_unpin(struct amdgpu_device *adev)
-{
-       int r;
-
-       if (!adev->gfx.rlc.clear_state_obj)
-               return;
-
-       r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
-       if (likely(r == 0)) {
-               amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-               amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-       }
-}
-
 static void gfx_v10_0_mec_fini(struct amdgpu_device *adev)
 {
        amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -1787,25 +1762,7 @@ static void gfx_v10_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
 
 static int gfx_v10_0_init_csb(struct amdgpu_device *adev)
 {
-       int r;
-
-       if (adev->in_gpu_reset) {
-               r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-               if (r)
-                       return r;
-
-               r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj,
-                                  (void **)&adev->gfx.rlc.cs_ptr);
-               if (!r) {
-                       adev->gfx.rlc.funcs->get_csb_buffer(adev,
-                                       adev->gfx.rlc.cs_ptr);
-                       amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
-               }
-
-               amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-               if (r)
-                       return r;
-       }
+       adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
 
        /* csib */
        WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI,
@@ -1817,22 +1774,6 @@ static int gfx_v10_0_init_csb(struct amdgpu_device *adev)
        return 0;
 }
 
-static int gfx_v10_0_init_pg(struct amdgpu_device *adev)
-{
-       int i;
-       int r;
-
-       r = gfx_v10_0_init_csb(adev);
-       if (r)
-               return r;
-
-       for (i = 0; i < adev->num_vmhubs; i++)
-               amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
-
-       /* TODO: init power gating */
-       return 0;
-}
-
 void gfx_v10_0_rlc_stop(struct amdgpu_device *adev)
 {
        u32 tmp = RREG32_SOC15(GC, 0, mmRLC_CNTL);
@@ -1925,21 +1866,16 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev)
 {
        int r;
 
-       if (amdgpu_sriov_vf(adev))
-               return 0;
-
        if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
-               r = gfx_v10_0_wait_for_rlc_autoload_complete(adev);
-               if (r)
-                       return r;
 
-               r = gfx_v10_0_init_pg(adev);
+               r = gfx_v10_0_wait_for_rlc_autoload_complete(adev);
                if (r)
                        return r;
 
-               /* enable RLC SRM */
-               gfx_v10_0_rlc_enable_srm(adev);
+               gfx_v10_0_init_csb(adev);
 
+               if (!amdgpu_sriov_vf(adev)) /* enable RLC SRM */
+                       gfx_v10_0_rlc_enable_srm(adev);
        } else {
                adev->gfx.rlc.funcs->stop(adev);
 
@@ -1961,9 +1897,7 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev)
                                return r;
                }
 
-               r = gfx_v10_0_init_pg(adev);
-               if (r)
-                       return r;
+               gfx_v10_0_init_csb(adev);
 
                adev->gfx.rlc.funcs->start(adev);
 
@@ -2825,7 +2759,7 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
        /* Init gfx ring 0 for pipe 0 */
        mutex_lock(&adev->srbm_mutex);
        gfx_v10_0_cp_gfx_switch_pipe(adev, PIPE_ID0);
-       mutex_unlock(&adev->srbm_mutex);
+
        /* Set ring buffer size */
        ring = &adev->gfx.gfx_ring[0];
        rb_bufsz = order_base_2(ring->ring_size / 8);
@@ -2863,11 +2797,11 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
        WREG32_SOC15(GC, 0, mmCP_RB_ACTIVE, 1);
 
        gfx_v10_0_cp_gfx_set_doorbell(adev, ring);
+       mutex_unlock(&adev->srbm_mutex);
 
        /* Init gfx ring 1 for pipe 1 */
        mutex_lock(&adev->srbm_mutex);
        gfx_v10_0_cp_gfx_switch_pipe(adev, PIPE_ID1);
-       mutex_unlock(&adev->srbm_mutex);
        ring = &adev->gfx.gfx_ring[1];
        rb_bufsz = order_base_2(ring->ring_size / 8);
        tmp = REG_SET_FIELD(0, CP_RB1_CNTL, RB_BUFSZ, rb_bufsz);
@@ -2897,6 +2831,7 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
        WREG32_SOC15(GC, 0, mmCP_RB1_ACTIVE, 1);
 
        gfx_v10_0_cp_gfx_set_doorbell(adev, ring);
+       mutex_unlock(&adev->srbm_mutex);
 
        /* Switch to pipe 0 */
        mutex_lock(&adev->srbm_mutex);
@@ -3775,10 +3710,6 @@ static int gfx_v10_0_hw_init(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       r = gfx_v10_0_csb_vram_pin(adev);
-       if (r)
-               return r;
-
        if (!amdgpu_emu_mode)
                gfx_v10_0_init_golden_registers(adev);
 
@@ -3861,12 +3792,11 @@ static int gfx_v10_0_hw_fini(void *handle)
        if (amdgpu_gfx_disable_kcq(adev))
                DRM_ERROR("KCQ disable failed\n");
        if (amdgpu_sriov_vf(adev)) {
-               pr_debug("For SRIOV client, shouldn't do anything.\n");
+               gfx_v10_0_cp_gfx_enable(adev, false);
                return 0;
        }
        gfx_v10_0_cp_enable(adev, false);
        gfx_v10_0_enable_gui_idle_interrupt(adev, false);
-       gfx_v10_0_csb_vram_unpin(adev);
 
        return 0;
 }
index 791ba39..d92e92e 100644 (file)
@@ -4554,6 +4554,8 @@ static int gfx_v7_0_hw_init(void *handle)
 
        gfx_v7_0_constants_init(adev);
 
+       /* init CSB */
+       adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
        /* init rlc */
        r = adev->gfx.rlc.funcs->resume(adev);
        if (r)
index ffbde91..52a647d 100644 (file)
@@ -1321,39 +1321,6 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
        return 0;
 }
 
-static int gfx_v8_0_csb_vram_pin(struct amdgpu_device *adev)
-{
-       int r;
-
-       r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-       if (unlikely(r != 0))
-               return r;
-
-       r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
-                       AMDGPU_GEM_DOMAIN_VRAM);
-       if (!r)
-               adev->gfx.rlc.clear_state_gpu_addr =
-                       amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
-
-       amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
-       return r;
-}
-
-static void gfx_v8_0_csb_vram_unpin(struct amdgpu_device *adev)
-{
-       int r;
-
-       if (!adev->gfx.rlc.clear_state_obj)
-               return;
-
-       r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
-       if (likely(r == 0)) {
-               amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-               amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-       }
-}
-
 static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
 {
        amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -3917,6 +3884,7 @@ static void gfx_v8_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
 
 static void gfx_v8_0_init_csb(struct amdgpu_device *adev)
 {
+       adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
        /* csib */
        WREG32(mmRLC_CSIB_ADDR_HI,
                        adev->gfx.rlc.clear_state_gpu_addr >> 32);
@@ -4837,10 +4805,6 @@ static int gfx_v8_0_hw_init(void *handle)
        gfx_v8_0_init_golden_registers(adev);
        gfx_v8_0_constants_init(adev);
 
-       r = gfx_v8_0_csb_vram_pin(adev);
-       if (r)
-               return r;
-
        r = adev->gfx.rlc.funcs->resume(adev);
        if (r)
                return r;
@@ -4958,8 +4922,6 @@ static int gfx_v8_0_hw_fini(void *handle)
                pr_err("rlc is busy, skip halt rlc\n");
        amdgpu_gfx_rlc_exit_safe_mode(adev);
 
-       gfx_v8_0_csb_vram_unpin(adev);
-
        return 0;
 }
 
@@ -6184,7 +6146,23 @@ static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr,
        bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT;
        bool int_sel = flags & AMDGPU_FENCE_FLAG_INT;
 
-       /* EVENT_WRITE_EOP - flush caches, send int */
+       /* Workaround for cache flush problems. First send a dummy EOP
+        * event down the pipe with seq one below.
+        */
+       amdgpu_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
+       amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN |
+                                EOP_TC_ACTION_EN |
+                                EOP_TC_WB_ACTION_EN |
+                                EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
+                                EVENT_INDEX(5)));
+       amdgpu_ring_write(ring, addr & 0xfffffffc);
+       amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) |
+                               DATA_SEL(1) | INT_SEL(0));
+       amdgpu_ring_write(ring, lower_32_bits(seq - 1));
+       amdgpu_ring_write(ring, upper_32_bits(seq - 1));
+
+       /* Then send the real EOP event down the pipe:
+        * EVENT_WRITE_EOP - flush caches, send int */
        amdgpu_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
        amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN |
                                 EOP_TC_ACTION_EN |
@@ -6926,7 +6904,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = {
                5 +  /* COND_EXEC */
                7 +  /* PIPELINE_SYNC */
                VI_FLUSH_GPU_TLB_NUM_WREG * 5 + 9 + /* VM_FLUSH */
-               8 +  /* FENCE for VM_FLUSH */
+               12 +  /* FENCE for VM_FLUSH */
                20 + /* GDS switch */
                4 + /* double SWITCH_BUFFER,
                       the first COND_EXEC jump to the place just
@@ -6938,7 +6916,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = {
                31 + /* DE_META */
                3 + /* CNTX_CTRL */
                5 + /* HDP_INVL */
-               8 + 8 + /* FENCE x2 */
+               12 + 12 + /* FENCE x2 */
                2, /* SWITCH_BUFFER */
        .emit_ib_size = 4, /* gfx_v8_0_ring_emit_ib_gfx */
        .emit_ib = gfx_v8_0_ring_emit_ib_gfx,
index faf2ffc..66328ff 100644 (file)
@@ -1695,39 +1695,6 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
        return 0;
 }
 
-static int gfx_v9_0_csb_vram_pin(struct amdgpu_device *adev)
-{
-       int r;
-
-       r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-       if (unlikely(r != 0))
-               return r;
-
-       r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
-                       AMDGPU_GEM_DOMAIN_VRAM);
-       if (!r)
-               adev->gfx.rlc.clear_state_gpu_addr =
-                       amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
-
-       amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
-       return r;
-}
-
-static void gfx_v9_0_csb_vram_unpin(struct amdgpu_device *adev)
-{
-       int r;
-
-       if (!adev->gfx.rlc.clear_state_obj)
-               return;
-
-       r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
-       if (likely(r == 0)) {
-               amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-               amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-       }
-}
-
 static void gfx_v9_0_mec_fini(struct amdgpu_device *adev)
 {
        amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -2415,6 +2382,7 @@ static void gfx_v9_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
 
 static void gfx_v9_0_init_csb(struct amdgpu_device *adev)
 {
+       adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
        /* csib */
        WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_ADDR_HI),
                        adev->gfx.rlc.clear_state_gpu_addr >> 32);
@@ -3706,10 +3674,6 @@ static int gfx_v9_0_hw_init(void *handle)
 
        gfx_v9_0_constants_init(adev);
 
-       r = gfx_v9_0_csb_vram_pin(adev);
-       if (r)
-               return r;
-
        r = adev->gfx.rlc.funcs->resume(adev);
        if (r)
                return r;
@@ -3791,8 +3755,6 @@ static int gfx_v9_0_hw_fini(void *handle)
        gfx_v9_0_cp_enable(adev, false);
        adev->gfx.rlc.funcs->stop(adev);
 
-       gfx_v9_0_csb_vram_unpin(adev);
-
        return 0;
 }
 
index 5e9ab8e..c0ab71d 100644 (file)
@@ -33,16 +33,31 @@ int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
        u32 xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL);
        u32 max_region =
                REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION);
+       u32 max_num_physical_nodes   = 0;
+       u32 max_physical_node_id     = 0;
+
+       switch (adev->asic_type) {
+       case CHIP_VEGA20:
+               max_num_physical_nodes   = 4;
+               max_physical_node_id     = 3;
+               break;
+       case CHIP_ARCTURUS:
+               max_num_physical_nodes   = 8;
+               max_physical_node_id     = 7;
+               break;
+       default:
+               return -EINVAL;
+       }
 
        /* PF_MAX_REGION=0 means xgmi is disabled */
        if (max_region) {
                adev->gmc.xgmi.num_physical_nodes = max_region + 1;
-               if (adev->gmc.xgmi.num_physical_nodes > 4)
+               if (adev->gmc.xgmi.num_physical_nodes > max_num_physical_nodes)
                        return -EINVAL;
 
                adev->gmc.xgmi.physical_node_id =
                        REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_LFB_REGION);
-               if (adev->gmc.xgmi.physical_node_id > 3)
+               if (adev->gmc.xgmi.physical_node_id > max_physical_node_id)
                        return -EINVAL;
                adev->gmc.xgmi.node_segment_size = REG_GET_FIELD(
                        RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_SIZE),
index 321f8a9..f572533 100644 (file)
@@ -219,6 +219,21 @@ static uint32_t gmc_v10_0_get_invalidate_req(unsigned int vmid,
        return req;
 }
 
+/**
+ * gmc_v10_0_use_invalidate_semaphore - judge whether to use semaphore
+ *
+ * @adev: amdgpu_device pointer
+ * @vmhub: vmhub type
+ *
+ */
+static bool gmc_v10_0_use_invalidate_semaphore(struct amdgpu_device *adev,
+                                      uint32_t vmhub)
+{
+       return ((vmhub == AMDGPU_MMHUB_0 ||
+                vmhub == AMDGPU_MMHUB_1) &&
+               (!amdgpu_sriov_vf(adev)));
+}
+
 /*
  * GART
  * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -229,6 +244,7 @@ static uint32_t gmc_v10_0_get_invalidate_req(unsigned int vmid,
 static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
                                   unsigned int vmhub, uint32_t flush_type)
 {
+       bool use_semaphore = gmc_v10_0_use_invalidate_semaphore(adev, vmhub);
        struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
        u32 tmp = gmc_v10_0_get_invalidate_req(vmid, flush_type);
        /* Use register 17 for GART */
@@ -244,8 +260,7 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
         */
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (vmhub == AMDGPU_MMHUB_0 ||
-           vmhub == AMDGPU_MMHUB_1) {
+       if (use_semaphore) {
                for (i = 0; i < adev->usec_timeout; i++) {
                        /* a read return value of 1 means semaphore acuqire */
                        tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng);
@@ -278,8 +293,7 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
        }
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (vmhub == AMDGPU_MMHUB_0 ||
-           vmhub == AMDGPU_MMHUB_1)
+       if (use_semaphore)
                /*
                 * add semaphore release after invalidation,
                 * write with 0 means semaphore release
@@ -326,7 +340,8 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
 
        if (!adev->mman.buffer_funcs_enabled ||
            !adev->ib_pool_ready ||
-           adev->in_gpu_reset) {
+           adev->in_gpu_reset ||
+           ring->sched.ready == false) {
                gmc_v10_0_flush_vm_hub(adev, vmid, AMDGPU_GFXHUB_0, 0);
                mutex_unlock(&adev->mman.gtt_window_lock);
                return;
@@ -368,6 +383,7 @@ error_alloc:
 static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
                                             unsigned vmid, uint64_t pd_addr)
 {
+       bool use_semaphore = gmc_v10_0_use_invalidate_semaphore(ring->adev, ring->funcs->vmhub);
        struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
        uint32_t req = gmc_v10_0_get_invalidate_req(vmid, 0);
        unsigned eng = ring->vm_inv_eng;
@@ -380,8 +396,7 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
         */
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
-           ring->funcs->vmhub == AMDGPU_MMHUB_1)
+       if (use_semaphore)
                /* a read return value of 1 means semaphore acuqire */
                amdgpu_ring_emit_reg_wait(ring,
                                          hub->vm_inv_eng0_sem + eng, 0x1, 0x1);
@@ -397,8 +412,7 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
                                            req, 1 << vmid);
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
-           ring->funcs->vmhub == AMDGPU_MMHUB_1)
+       if (use_semaphore)
                /*
                 * add semaphore release after invalidation,
                 * write with 0 means semaphore release
index 3c355fb..a5b68b5 100644 (file)
@@ -416,6 +416,24 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid,
        return req;
 }
 
+/**
+ * gmc_v9_0_use_invalidate_semaphore - judge whether to use semaphore
+ *
+ * @adev: amdgpu_device pointer
+ * @vmhub: vmhub type
+ *
+ */
+static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev,
+                                      uint32_t vmhub)
+{
+       return ((vmhub == AMDGPU_MMHUB_0 ||
+                vmhub == AMDGPU_MMHUB_1) &&
+               (!amdgpu_sriov_vf(adev)) &&
+               (!(adev->asic_type == CHIP_RAVEN &&
+                  adev->rev_id < 0x8 &&
+                  adev->pdev->device == 0x15d8)));
+}
+
 /*
  * GART
  * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -435,6 +453,7 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid,
 static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
                                        uint32_t vmhub, uint32_t flush_type)
 {
+       bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
        const unsigned eng = 17;
        u32 j, tmp;
        struct amdgpu_vmhub *hub;
@@ -468,8 +487,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
         */
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (vmhub == AMDGPU_MMHUB_0 ||
-           vmhub == AMDGPU_MMHUB_1) {
+       if (use_semaphore) {
                for (j = 0; j < adev->usec_timeout; j++) {
                        /* a read return value of 1 means semaphore acuqire */
                        tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng);
@@ -499,8 +517,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
        }
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (vmhub == AMDGPU_MMHUB_0 ||
-           vmhub == AMDGPU_MMHUB_1)
+       if (use_semaphore)
                /*
                 * add semaphore release after invalidation,
                 * write with 0 means semaphore release
@@ -518,6 +535,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
 static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
                                            unsigned vmid, uint64_t pd_addr)
 {
+       bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(ring->adev, ring->funcs->vmhub);
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_vmhub *hub = &adev->vmhub[ring->funcs->vmhub];
        uint32_t req = gmc_v9_0_get_invalidate_req(vmid, 0);
@@ -531,8 +549,7 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
         */
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
-           ring->funcs->vmhub == AMDGPU_MMHUB_1)
+       if (use_semaphore)
                /* a read return value of 1 means semaphore acuqire */
                amdgpu_ring_emit_reg_wait(ring,
                                          hub->vm_inv_eng0_sem + eng, 0x1, 0x1);
@@ -548,8 +565,7 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
                                            req, 1 << vmid);
 
        /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
-       if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
-           ring->funcs->vmhub == AMDGPU_MMHUB_1)
+       if (use_semaphore)
                /*
                 * add semaphore release after invalidation,
                 * write with 0 means semaphore release
index 78e5cdc..f1b171e 100644 (file)
@@ -783,10 +783,13 @@ static int vi_asic_reset(struct amdgpu_device *adev)
 {
        int r;
 
-       if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
+       if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
+               if (!adev->in_suspend)
+                       amdgpu_inc_vram_lost(adev);
                r = smu7_asic_baco_reset(adev);
-       else
+       } else {
                r = vi_asic_pci_config_reset(adev);
+       }
 
        return r;
 }
index a1a35d4..b3672d1 100644 (file)
@@ -1,11 +1,11 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: MIT
 #
 # Heterogenous system architecture configuration
 #
 
 config HSA_AMD
        bool "HSA kernel driver for AMD GPU devices"
-       depends on DRM_AMDGPU && (X86_64 || ARM64)
+       depends on DRM_AMDGPU && (X86_64 || ARM64 || PPC64)
        imply AMD_IOMMU_V2 if X86_64
        select MMU_NOTIFIER
        help
index 313183b..ae161fe 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: MIT
 menu "Display Engine Configuration"
        depends on DRM && DRM_AMDGPU
 
index 55a520a..778f186 100644 (file)
@@ -342,7 +342,8 @@ bool dm_pp_get_clock_levels_by_type(
        if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
                if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
                        dc_to_pp_clock_type(clk_type), &pp_clks)) {
-               /* Error in pplib. Provide default values. */
+                       /* Error in pplib. Provide default values. */
+                       get_default_clock_levels(clk_type, dc_clks);
                        return true;
                }
        } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type) {
index 7873abe..5c3fcaa 100644 (file)
@@ -1625,6 +1625,7 @@ static enum bp_result construct_integrated_info(
                /* Don't need to check major revision as they are all 1 */
                switch (revision.minor) {
                case 11:
+               case 12:
                        result = get_integrated_info_v11(bp, info);
                        break;
                default:
index 790a2d2..35c55e5 100644 (file)
@@ -471,12 +471,28 @@ static void rn_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
 
 }
 
+static bool rn_are_clock_states_equal(struct dc_clocks *a,
+               struct dc_clocks *b)
+{
+       if (a->dispclk_khz != b->dispclk_khz)
+               return false;
+       else if (a->dppclk_khz != b->dppclk_khz)
+               return false;
+       else if (a->dcfclk_khz != b->dcfclk_khz)
+               return false;
+       else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz)
+               return false;
+
+       return true;
+}
+
+
 static struct clk_mgr_funcs dcn21_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
        .update_clocks = rn_update_clocks,
        .init_clocks = rn_init_clocks,
        .enable_pme_wa = rn_enable_pme_wa,
-       /* .dump_clk_registers = rn_dump_clk_registers, */
+       .are_clock_states_equal = rn_are_clock_states_equal,
        .notify_wm_ranges = rn_notify_wm_ranges
 };
 
@@ -518,36 +534,83 @@ struct clk_bw_params rn_bw_params = {
                .num_entries = 4,
        },
 
-       .wm_table = {
-               .entries = {
-                       {
-                               .wm_inst = WM_A,
-                               .wm_type = WM_TYPE_PSTATE_CHG,
-                               .pstate_latency_us = 23.84,
-                               .valid = true,
-                       },
-                       {
-                               .wm_inst = WM_B,
-                               .wm_type = WM_TYPE_PSTATE_CHG,
-                               .pstate_latency_us = 23.84,
-                               .valid = true,
-                       },
-                       {
-                               .wm_inst = WM_C,
-                               .wm_type = WM_TYPE_PSTATE_CHG,
-                               .pstate_latency_us = 23.84,
-                               .valid = true,
-                       },
-                       {
-                               .wm_inst = WM_D,
-                               .wm_type = WM_TYPE_PSTATE_CHG,
-                               .pstate_latency_us = 23.84,
-                               .valid = true,
-                       },
+};
+
+struct wm_table ddr4_wm_table = {
+       .entries = {
+               {
+                       .wm_inst = WM_A,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+                       .sr_exit_time_us = 6.09,
+                       .sr_enter_plus_exit_time_us = 7.14,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_B,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+                       .sr_exit_time_us = 10.12,
+                       .sr_enter_plus_exit_time_us = 11.48,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_C,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+                       .sr_exit_time_us = 10.12,
+                       .sr_enter_plus_exit_time_us = 11.48,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_D,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+                       .sr_exit_time_us = 10.12,
+                       .sr_enter_plus_exit_time_us = 11.48,
+                       .valid = true,
                },
        }
 };
 
+struct wm_table lpddr4_wm_table = {
+       .entries = {
+               {
+                       .wm_inst = WM_A,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 23.84,
+                       .sr_exit_time_us = 12.5,
+                       .sr_enter_plus_exit_time_us = 17.0,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_B,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 23.84,
+                       .sr_exit_time_us = 12.5,
+                       .sr_enter_plus_exit_time_us = 17.0,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_C,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 23.84,
+                       .sr_exit_time_us = 12.5,
+                       .sr_enter_plus_exit_time_us = 17.0,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_D,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 23.84,
+                       .sr_exit_time_us = 12.5,
+                       .sr_enter_plus_exit_time_us = 17.0,
+                       .valid = true,
+               },
+       }
+};
+
+
 static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
 {
        int i;
@@ -561,7 +624,7 @@ static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsi
        return 0;
 }
 
-static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
+static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct integrated_info *bios_info)
 {
        int i, j = 0;
 
@@ -593,8 +656,8 @@ static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params
                bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->FClocks[j].Vol);
        }
 
-       bw_params->vram_type = asic_id->vram_type;
-       bw_params->num_channels = asic_id->vram_width / DDR4_DRAM_WIDTH;
+       bw_params->vram_type = bios_info->memory_type;
+       bw_params->num_channels = bios_info->ma_channel_number;
 
        for (i = 0; i < WM_SET_COUNT; i++) {
                bw_params->wm_table.entries[i].wm_inst = i;
@@ -669,15 +732,24 @@ void rn_clk_mgr_construct(
                        ASSERT(clk_mgr->base.dprefclk_khz == 600000);
                        clk_mgr->base.dprefclk_khz = 600000;
                }
+
+               if (ctx->dc_bios->integrated_info->memory_type == LpDdr4MemType) {
+                       rn_bw_params.wm_table = lpddr4_wm_table;
+               } else {
+                       rn_bw_params.wm_table = ddr4_wm_table;
+               }
        }
 
        dce_clock_read_ss_info(clk_mgr);
 
+
        clk_mgr->base.bw_params = &rn_bw_params;
 
        if (pp_smu && pp_smu->rn_funcs.get_dpm_clock_table) {
                pp_smu->rn_funcs.get_dpm_clock_table(&pp_smu->rn_funcs.pp_smu, &clock_table);
-               rn_clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id);
+               if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
+                       rn_clk_mgr_helper_populate_bw_params (clk_mgr->base.bw_params, &clock_table, ctx->dc_bios->integrated_info);
+               }
        }
 
        if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) {
index 12ba6fd..62d8289 100644 (file)
@@ -372,7 +372,7 @@ bool dc_link_is_dp_sink_present(struct dc_link *link)
 
        if (GPIO_RESULT_OK != dal_ddc_open(
                ddc, GPIO_MODE_INPUT, GPIO_DDC_CONFIG_TYPE_MODE_I2C)) {
-               dal_gpio_destroy_ddc(&ddc);
+               dal_ddc_close(ddc);
 
                return present;
        }
index 7f904d5..8178919 100644 (file)
@@ -586,7 +586,7 @@ bool dal_ddc_service_query_ddc_data(
 bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
                struct aux_payload *payload)
 {
-       uint8_t retrieved = 0;
+       uint32_t retrieved = 0;
        bool ret = 0;
 
        if (!ddc)
index 0f59b68..504055f 100644 (file)
@@ -3522,7 +3522,14 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
        if (link_enc->funcs->fec_set_enable &&
                        link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
                if (link->fec_state == dc_link_fec_ready && enable) {
-                       msleep(1);
+                       /* Accord to DP spec, FEC enable sequence can first
+                        * be transmitted anytime after 1000 LL codes have
+                        * been transmitted on the link after link training
+                        * completion. Using 1 lane RBR should have the maximum
+                        * time for transmitting 1000 LL codes which is 6.173 us.
+                        * So use 7 microseconds delay instead.
+                        */
+                       udelay(7);
                        link_enc->funcs->fec_set_enable(link_enc, true);
                        link->fec_state = dc_link_fec_enabled;
                } else if (link->fec_state == dc_link_fec_enabled && !enable) {
index e472608..793c0ce 100644 (file)
@@ -583,6 +583,8 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
        uint8_t reply;
        bool payload_reply = true;
        enum aux_channel_operation_result operation_result;
+       bool retry_on_defer = false;
+
        int aux_ack_retries = 0,
                aux_defer_retries = 0,
                aux_i2c_defer_retries = 0,
@@ -613,8 +615,10 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
                        break;
 
                        case AUX_TRANSACTION_REPLY_AUX_DEFER:
-                       case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
                        case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
+                               retry_on_defer = true;
+                               /* fall through */
+                       case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
                                if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) {
                                        goto fail;
                                } else {
@@ -647,15 +651,24 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
                        break;
 
                case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
-                       if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES)
-                               goto fail;
-                       else {
-                               /*
-                                * DP 1.4, 2.8.2:  AUX Transaction Response/Reply Timeouts
-                                * According to the DP spec there should be 3 retries total
-                                * with a 400us wait inbetween each. Hardware already waits
-                                * for 550us therefore no wait is required here.
-                                */
+                       // Check whether a DEFER had occurred before the timeout.
+                       // If so, treat timeout as a DEFER.
+                       if (retry_on_defer) {
+                               if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES)
+                                       goto fail;
+                               else if (payload->defer_delay > 0)
+                                       msleep(payload->defer_delay);
+                       } else {
+                               if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES)
+                                       goto fail;
+                               else {
+                                       /*
+                                        * DP 1.4, 2.8.2:  AUX Transaction Response/Reply Timeouts
+                                        * According to the DP spec there should be 3 retries total
+                                        * with a 400us wait inbetween each. Hardware already waits
+                                        * for 550us therefore no wait is required here.
+                                        */
+                               }
                        }
                        break;
 
index 921a366..ac8c18f 100644 (file)
@@ -1037,6 +1037,25 @@ void dcn20_pipe_control_lock(
        if (pipe->plane_state != NULL)
                flip_immediate = pipe->plane_state->flip_immediate;
 
+       if (flip_immediate && lock) {
+               const int TIMEOUT_FOR_FLIP_PENDING = 100000;
+               int i;
+
+               for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) {
+                       if (!pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp))
+                               break;
+                       udelay(1);
+               }
+
+               if (pipe->bottom_pipe != NULL) {
+                       for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) {
+                               if (!pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp))
+                                       break;
+                               udelay(1);
+                       }
+               }
+       }
+
        /* In flip immediate and pipe splitting case, we need to use GSL
         * for synchronization. Only do setup on locking and on flip type change.
         */
index bbd1c98..23ff2f1 100644 (file)
@@ -157,6 +157,74 @@ struct _vcs_dpi_ip_params_st dcn2_0_ip = {
        .xfc_fill_constant_bytes = 0,
 };
 
+struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {
+       .odm_capable = 1,
+       .gpuvm_enable = 0,
+       .hostvm_enable = 0,
+       .gpuvm_max_page_table_levels = 4,
+       .hostvm_max_page_table_levels = 4,
+       .hostvm_cached_page_table_levels = 0,
+       .num_dsc = 5,
+       .rob_buffer_size_kbytes = 168,
+       .det_buffer_size_kbytes = 164,
+       .dpte_buffer_size_in_pte_reqs_luma = 84,
+       .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
+       .dpp_output_buffer_pixels = 2560,
+       .opp_output_buffer_lines = 1,
+       .pixel_chunk_size_kbytes = 8,
+       .pte_enable = 1,
+       .max_page_table_levels = 4,
+       .pte_chunk_size_kbytes = 2,
+       .meta_chunk_size_kbytes = 2,
+       .writeback_chunk_size_kbytes = 2,
+       .line_buffer_size_bits = 789504,
+       .is_line_buffer_bpp_fixed = 0,
+       .line_buffer_fixed_bpp = 0,
+       .dcc_supported = true,
+       .max_line_buffer_lines = 12,
+       .writeback_luma_buffer_size_kbytes = 12,
+       .writeback_chroma_buffer_size_kbytes = 8,
+       .writeback_chroma_line_buffer_width_pixels = 4,
+       .writeback_max_hscl_ratio = 1,
+       .writeback_max_vscl_ratio = 1,
+       .writeback_min_hscl_ratio = 1,
+       .writeback_min_vscl_ratio = 1,
+       .writeback_max_hscl_taps = 12,
+       .writeback_max_vscl_taps = 12,
+       .writeback_line_buffer_luma_buffer_size = 0,
+       .writeback_line_buffer_chroma_buffer_size = 14643,
+       .cursor_buffer_size = 8,
+       .cursor_chunk_size = 2,
+       .max_num_otg = 5,
+       .max_num_dpp = 5,
+       .max_num_wb = 1,
+       .max_dchub_pscl_bw_pix_per_clk = 4,
+       .max_pscl_lb_bw_pix_per_clk = 2,
+       .max_lb_vscl_bw_pix_per_clk = 4,
+       .max_vscl_hscl_bw_pix_per_clk = 4,
+       .max_hscl_ratio = 8,
+       .max_vscl_ratio = 8,
+       .hscl_mults = 4,
+       .vscl_mults = 4,
+       .max_hscl_taps = 8,
+       .max_vscl_taps = 8,
+       .dispclk_ramp_margin_percent = 1,
+       .underscan_factor = 1.10,
+       .min_vblank_lines = 32, //
+       .dppclk_delay_subtotal = 77, //
+       .dppclk_delay_scl_lb_only = 16,
+       .dppclk_delay_scl = 50,
+       .dppclk_delay_cnvc_formatter = 8,
+       .dppclk_delay_cnvc_cursor = 6,
+       .dispclk_delay_subtotal = 87, //
+       .dcfclk_cstate_latency = 10, // SRExitTime
+       .max_inter_dcn_tile_repeaters = 8,
+       .xfc_supported = true,
+       .xfc_fill_bw_overhead_percent = 10.0,
+       .xfc_fill_constant_bytes = 0,
+       .ptoi_supported = 0
+};
+
 struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
        /* Defaults that get patched on driver load from firmware. */
        .clock_limits = {
@@ -854,6 +922,10 @@ static const struct resource_caps res_cap_nv14 = {
                .num_pll = 5,
                .num_dwb = 1,
                .num_ddc = 5,
+               .num_vmid = 16,
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+               .num_dsc = 5,
+#endif
 };
 
 static const struct dc_debug_options debug_defaults_drv = {
@@ -1466,13 +1538,20 @@ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state
 
 static void acquire_dsc(struct resource_context *res_ctx,
                        const struct resource_pool *pool,
-                       struct display_stream_compressor **dsc)
+                       struct display_stream_compressor **dsc,
+                       int pipe_idx)
 {
        int i;
 
        ASSERT(*dsc == NULL);
        *dsc = NULL;
 
+       if (pool->res_cap->num_dsc == pool->res_cap->num_opp) {
+               *dsc = pool->dscs[pipe_idx];
+               res_ctx->is_dsc_acquired[pipe_idx] = true;
+               return;
+       }
+
        /* Find first free DSC */
        for (i = 0; i < pool->res_cap->num_dsc; i++)
                if (!res_ctx->is_dsc_acquired[i]) {
@@ -1515,7 +1594,7 @@ static enum dc_status add_dsc_to_stream_resource(struct dc *dc,
                if (pipe_ctx->stream != dc_stream)
                        continue;
 
-               acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc);
+               acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc, i);
 
                /* The number of DSCs can be less than the number of pipes */
                if (!pipe_ctx->stream_res.dsc) {
@@ -1715,7 +1794,7 @@ bool dcn20_split_stream_for_odm(
        next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx];
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
        if (next_odm_pipe->stream->timing.flags.DSC == 1) {
-               acquire_dsc(res_ctx, pool, &next_odm_pipe->stream_res.dsc);
+               acquire_dsc(res_ctx, pool, &next_odm_pipe->stream_res.dsc, next_odm_pipe->pipe_idx);
                ASSERT(next_odm_pipe->stream_res.dsc);
                if (next_odm_pipe->stream_res.dsc == NULL)
                        return false;
@@ -3212,6 +3291,10 @@ static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb(
 static struct _vcs_dpi_ip_params_st *get_asic_rev_ip_params(
        uint32_t hw_internal_rev)
 {
+       /* NV14 */
+       if (ASICREV_IS_NAVI14_M(hw_internal_rev))
+               return &dcn2_0_nv14_ip;
+
        /* NV12 and NV10 */
        return &dcn2_0_ip;
 }
index 4b34016..fcb3877 100644 (file)
@@ -492,15 +492,23 @@ void enc2_stream_encoder_dp_unblank(
                                DP_VID_N_MUL, n_multiply);
        }
 
-       /* set DIG_START to 0x1 to reset FIFO */
+       /* make sure stream is disabled before resetting steer fifo */
+       REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false);
+       REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000);
 
+       /* set DIG_START to 0x1 to reset FIFO */
        REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
+       udelay(1);
 
        /* write 0 to take the FIFO out of reset */
 
        REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
 
-       /* switch DP encoder to CRTC data */
+       /* switch DP encoder to CRTC data, but reset it the fifo first. It may happen
+        * that it overflows during mode transition, and sometimes doesn't recover.
+        */
+       REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1);
+       udelay(10);
 
        REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
 
index 459bd9a..b29b2c9 100644 (file)
@@ -23,6 +23,8 @@
  *
  */
 
+#include <linux/slab.h>
+
 #include "dm_services.h"
 #include "dc.h"
 
@@ -257,7 +259,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
        .vmm_page_size_bytes = 4096,
        .dram_clock_change_latency_us = 23.84,
        .return_bus_width_bytes = 64,
-       .dispclk_dppclk_vco_speed_mhz = 3550,
+       .dispclk_dppclk_vco_speed_mhz = 3600,
        .xfc_bus_transport_time_us = 4,
        .xfc_xbuf_latency_tolerance_us = 4,
        .use_urgent_burst_bw = 1,
@@ -1000,6 +1002,8 @@ static void calculate_wm_set_for_vlevel(
        pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
 
        dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
+       dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
+       dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
 
        wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
        wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
@@ -1017,14 +1021,21 @@ static void calculate_wm_set_for_vlevel(
 
 static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
 {
+       int i;
+
        kernel_fpu_begin();
        if (dc->bb_overrides.sr_exit_time_ns) {
-               bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
+               for (i = 0; i < WM_SET_COUNT; i++) {
+                         dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
+                                         dc->bb_overrides.sr_exit_time_ns / 1000.0;
+               }
        }
 
        if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
-               bb->sr_enter_plus_exit_time_us =
-                               dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
+               for (i = 0; i < WM_SET_COUNT; i++) {
+                         dc->clk_mgr->bw_params->wm_table.entries[i].sr_enter_plus_exit_time_us =
+                                         dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
+               }
        }
 
        if (dc->bb_overrides.urgent_latency_ns) {
@@ -1032,9 +1043,12 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s
        }
 
        if (dc->bb_overrides.dram_clock_change_latency_ns) {
-               bb->dram_clock_change_latency_us =
+               for (i = 0; i < WM_SET_COUNT; i++) {
+                       dc->clk_mgr->bw_params->wm_table.entries[i].pstate_latency_us =
                                dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
+               }
        }
+
        kernel_fpu_end();
 }
 
index 9707372..641ffb7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
 #
 # Makefile for the 'dsc' sub-component of DAL.
 
index 4e18e77..026e6a2 100644 (file)
@@ -69,6 +69,8 @@ struct wm_range_table_entry {
        unsigned int wm_inst;
        unsigned int wm_type;
        double pstate_latency_us;
+       double sr_exit_time_us;
+       double sr_enter_plus_exit_time_us;
        bool valid;
 };
 
index bb012cb..c7fbb9c 100644 (file)
@@ -42,7 +42,7 @@ struct aux_payload {
        bool write;
        bool mot;
        uint32_t address;
-       uint8_t length;
+       uint32_t length;
        uint8_t *data;
        /*
         * used to return the reply type of the transaction
index 16e69bb..5437b50 100644 (file)
@@ -37,8 +37,8 @@
 #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65)
 /* Number of elements in the render times cache array */
 #define RENDER_TIMES_MAX_COUNT 10
-/* Threshold to exit/exit BTR (to avoid frequent enter-exits at the lower limit) */
-#define BTR_MAX_MARGIN 2500
+/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */
+#define BTR_EXIT_MARGIN 2000
 /* Threshold to change BTR multiplier (to avoid frequent changes) */
 #define BTR_DRIFT_MARGIN 2000
 /*Threshold to exit fixed refresh rate*/
@@ -254,22 +254,24 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
        unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF;
        unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF;
        unsigned int frames_to_insert = 0;
+       unsigned int min_frame_duration_in_ns = 0;
+       unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us;
        unsigned int delta_from_mid_point_delta_in_us;
-       unsigned int max_render_time_in_us =
-                       in_out_vrr->max_duration_in_us - in_out_vrr->btr.margin_in_us;
+
+       min_frame_duration_in_ns = ((unsigned int) (div64_u64(
+               (1000000000ULL * 1000000),
+               in_out_vrr->max_refresh_in_uhz)));
 
        /* Program BTR */
-       if ((last_render_time_in_us + in_out_vrr->btr.margin_in_us / 2) < max_render_time_in_us) {
+       if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) {
                /* Exit Below the Range */
                if (in_out_vrr->btr.btr_active) {
                        in_out_vrr->btr.frame_counter = 0;
                        in_out_vrr->btr.btr_active = false;
                }
-       } else if (last_render_time_in_us > (max_render_time_in_us + in_out_vrr->btr.margin_in_us / 2)) {
+       } else if (last_render_time_in_us > max_render_time_in_us) {
                /* Enter Below the Range */
-               if (!in_out_vrr->btr.btr_active) {
-                       in_out_vrr->btr.btr_active = true;
-               }
+               in_out_vrr->btr.btr_active = true;
        }
 
        /* BTR set to "not active" so disengage */
@@ -325,9 +327,7 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
                /* Choose number of frames to insert based on how close it
                 * can get to the mid point of the variable range.
                 */
-               if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us &&
-                               (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 ||
-                                               mid_point_frames_floor < 2)) {
+               if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
                        frames_to_insert = mid_point_frames_ceil;
                        delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
                                        delta_from_mid_point_in_us_1;
@@ -343,7 +343,7 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
                if (in_out_vrr->btr.frames_to_insert != 0 &&
                                delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) {
                        if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) <
-                                       max_render_time_in_us) &&
+                                       in_out_vrr->max_duration_in_us) &&
                                ((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) >
                                        in_out_vrr->min_duration_in_us))
                                frames_to_insert = in_out_vrr->btr.frames_to_insert;
@@ -796,11 +796,6 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
                refresh_range = in_out_vrr->max_refresh_in_uhz -
                                in_out_vrr->min_refresh_in_uhz;
 
-               in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us -
-                               2 * in_out_vrr->min_duration_in_us;
-               if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN)
-                       in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN;
-
                in_out_vrr->supported = true;
        }
 
@@ -816,7 +811,6 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
        in_out_vrr->btr.inserted_duration_in_us = 0;
        in_out_vrr->btr.frames_to_insert = 0;
        in_out_vrr->btr.frame_counter = 0;
-
        in_out_vrr->btr.mid_point_in_us =
                                (in_out_vrr->min_duration_in_us +
                                 in_out_vrr->max_duration_in_us) / 2;
index dbe7835..dc18784 100644 (file)
@@ -92,7 +92,6 @@ struct mod_vrr_params_btr {
        uint32_t inserted_duration_in_us;
        uint32_t frames_to_insert;
        uint32_t frame_counter;
-       uint32_t margin_in_us;
 };
 
 struct mod_vrr_params_fixed_refresh {
index 40b546c..5ff7cce 100644 (file)
@@ -2548,3 +2548,12 @@ uint32_t smu_get_pptable_power_limit(struct smu_context *smu)
 
        return ret;
 }
+
+int smu_send_smc_msg(struct smu_context *smu,
+                    enum smu_message_type msg)
+{
+       int ret;
+
+       ret = smu_send_smc_msg_with_param(smu, msg, 0);
+       return ret;
+}
index 58c7c4a..cc71a10 100644 (file)
@@ -1313,12 +1313,17 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu,
                                        "VR",
                                        "COMPUTE",
                                        "CUSTOM"};
+       static const char *title[] = {
+                       "PROFILE_INDEX(NAME)"};
        uint32_t i, size = 0;
        int16_t workload_type = 0;
 
        if (!smu->pm_enabled || !buf)
                return -EINVAL;
 
+       size += sprintf(buf + size, "%16s\n",
+                       title[0]);
+
        for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
                /*
                 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
@@ -2130,7 +2135,6 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
        .set_tool_table_location = smu_v11_0_set_tool_table_location,
        .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
        .system_features_control = smu_v11_0_system_features_control,
-       .send_smc_msg = smu_v11_0_send_msg,
        .send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
        .read_smc_arg = smu_v11_0_read_arg,
        .init_display_count = smu_v11_0_init_display_count,
index 031e0c2..ac97583 100644 (file)
@@ -497,8 +497,8 @@ struct pptable_funcs {
        int (*notify_memory_pool_location)(struct smu_context *smu);
        int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu);
        int (*system_features_control)(struct smu_context *smu, bool en);
-       int (*send_smc_msg)(struct smu_context *smu, uint16_t msg);
-       int (*send_smc_msg_with_param)(struct smu_context *smu, uint16_t msg, uint32_t param);
+       int (*send_smc_msg_with_param)(struct smu_context *smu,
+                                      enum smu_message_type msg, uint32_t param);
        int (*read_smc_arg)(struct smu_context *smu, uint32_t *arg);
        int (*init_display_count)(struct smu_context *smu, uint32_t count);
        int (*set_allowed_mask)(struct smu_context *smu);
index 6061490..7198442 100644 (file)
@@ -177,10 +177,9 @@ int smu_v11_0_notify_memory_pool_location(struct smu_context *smu);
 int smu_v11_0_system_features_control(struct smu_context *smu,
                                             bool en);
 
-int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg);
-
 int
-smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v11_0_send_msg_with_param(struct smu_context *smu,
+                             enum smu_message_type msg,
                              uint32_t param);
 
 int smu_v11_0_read_arg(struct smu_context *smu, uint32_t *arg);
index 9b9f5df..9d81d78 100644 (file)
@@ -44,10 +44,9 @@ int smu_v12_0_read_arg(struct smu_context *smu, uint32_t *arg);
 
 int smu_v12_0_wait_for_response(struct smu_context *smu);
 
-int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg);
-
 int
-smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v12_0_send_msg_with_param(struct smu_context *smu,
+                             enum smu_message_type msg,
                              uint32_t param);
 
 int smu_v12_0_check_fw_status(struct smu_context *smu);
index aaec884..4a14fd1 100644 (file)
@@ -2055,7 +2055,6 @@ static const struct pptable_funcs navi10_ppt_funcs = {
        .set_tool_table_location = smu_v11_0_set_tool_table_location,
        .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
        .system_features_control = smu_v11_0_system_features_control,
-       .send_smc_msg = smu_v11_0_send_msg,
        .send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
        .read_smc_arg = smu_v11_0_read_arg,
        .init_display_count = smu_v11_0_init_display_count,
index 04daf7e..977bdd9 100644 (file)
@@ -697,7 +697,6 @@ static const struct pptable_funcs renoir_ppt_funcs = {
        .check_fw_version = smu_v12_0_check_fw_version,
        .powergate_sdma = smu_v12_0_powergate_sdma,
        .powergate_vcn = smu_v12_0_powergate_vcn,
-       .send_smc_msg = smu_v12_0_send_msg,
        .send_smc_msg_with_param = smu_v12_0_send_msg_with_param,
        .read_smc_arg = smu_v12_0_read_arg,
        .set_gfx_cgpg = smu_v12_0_set_gfx_cgpg,
index 8bcda78..8872f8b 100644 (file)
@@ -75,8 +75,8 @@
 #define smu_set_default_od_settings(smu, initialize) \
        ((smu)->ppt_funcs->set_default_od_settings ? (smu)->ppt_funcs->set_default_od_settings((smu), (initialize)) : 0)
 
-#define smu_send_smc_msg(smu, msg) \
-       ((smu)->ppt_funcs->send_smc_msg? (smu)->ppt_funcs->send_smc_msg((smu), (msg)) : 0)
+int smu_send_smc_msg(struct smu_context *smu, enum smu_message_type msg);
+
 #define smu_send_smc_msg_with_param(smu, msg, param) \
        ((smu)->ppt_funcs->send_smc_msg_with_param? (smu)->ppt_funcs->send_smc_msg_with_param((smu), (msg), (param)) : 0)
 #define smu_read_smc_arg(smu, arg) \
index fc9679e..e4268a6 100644 (file)
@@ -90,36 +90,11 @@ static int smu_v11_0_wait_for_response(struct smu_context *smu)
        return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
 }
 
-int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg)
-{
-       struct amdgpu_device *adev = smu->adev;
-       int ret = 0, index = 0;
-
-       index = smu_msg_get_index(smu, msg);
-       if (index < 0)
-               return index;
-
-       smu_v11_0_wait_for_response(smu);
-
-       WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
-
-       smu_v11_0_send_msg_without_waiting(smu, (uint16_t)index);
-
-       ret = smu_v11_0_wait_for_response(smu);
-
-       if (ret)
-               pr_err("failed send message: %10s (%d) response %#x\n",
-                      smu_get_message_name(smu, msg), index, ret);
-
-       return ret;
-
-}
-
 int
-smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v11_0_send_msg_with_param(struct smu_context *smu,
+                             enum smu_message_type msg,
                              uint32_t param)
 {
-
        struct amdgpu_device *adev = smu->adev;
        int ret = 0, index = 0;
 
index 139dd73..094cfc4 100644 (file)
@@ -77,33 +77,9 @@ int smu_v12_0_wait_for_response(struct smu_context *smu)
        return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
 }
 
-int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg)
-{
-       struct amdgpu_device *adev = smu->adev;
-       int ret = 0, index = 0;
-
-       index = smu_msg_get_index(smu, msg);
-       if (index < 0)
-               return index;
-
-       smu_v12_0_wait_for_response(smu);
-
-       WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
-
-       smu_v12_0_send_msg_without_waiting(smu, (uint16_t)index);
-
-       ret = smu_v12_0_wait_for_response(smu);
-
-       if (ret)
-               pr_err("Failed to send message 0x%x, response 0x%x\n", index,
-                      ret);
-
-       return ret;
-
-}
-
 int
-smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v12_0_send_msg_with_param(struct smu_context *smu,
+                             enum smu_message_type msg,
                              uint32_t param)
 {
        struct amdgpu_device *adev = smu->adev;
index 0b48928..60b9ff0 100644 (file)
@@ -3231,7 +3231,6 @@ static const struct pptable_funcs vega20_ppt_funcs = {
        .set_tool_table_location = smu_v11_0_set_tool_table_location,
        .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
        .system_features_control = smu_v11_0_system_features_control,
-       .send_smc_msg = smu_v11_0_send_msg,
        .send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
        .read_smc_arg = smu_v11_0_read_arg,
        .init_display_count = smu_v11_0_init_display_count,
index ae5809a..273dd80 100644 (file)
@@ -3176,9 +3176,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
                        drm_dp_mst_topology_put_port(port);
        }
 
-       for (i = 0; i < mgr->max_payloads; i++) {
-               if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL)
+       for (i = 0; i < mgr->max_payloads; /* do nothing */) {
+               if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) {
+                       i++;
                        continue;
+               }
 
                DRM_DEBUG_KMS("removing payload %d\n", i);
                for (j = i; j < mgr->max_payloads - 1; j++) {
index 892ce63..6ee0480 100644 (file)
@@ -561,7 +561,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
        struct drm_property_blob *blob;
        int ret;
 
-       if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
+       if (!length || length > INT_MAX - sizeof(struct drm_property_blob))
                return ERR_PTR(-EINVAL);
 
        blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
index 1799537..c280b6a 100644 (file)
@@ -25,7 +25,7 @@ config DRM_I915_HEARTBEAT_INTERVAL
 
 config DRM_I915_PREEMPT_TIMEOUT
        int "Preempt timeout (ms, jiffy granularity)"
-       default 100 # milliseconds
+       default 640 # milliseconds
        help
          How long to wait (in milliseconds) for a preemption event to occur
          when submitting a new context via execlists. If the current context
index 0caef25..ed8c7ce 100644 (file)
@@ -1273,7 +1273,9 @@ static u8 icl_calc_voltage_level(int cdclk)
 
 static u8 ehl_calc_voltage_level(int cdclk)
 {
-       if (cdclk > 312000)
+       if (cdclk > 326400)
+               return 3;
+       else if (cdclk > 312000)
                return 2;
        else if (cdclk > 180000)
                return 1;
index 0d6e494..2a27fb5 100644 (file)
@@ -593,7 +593,7 @@ struct tgl_dkl_phy_ddi_buf_trans {
        u32 dkl_de_emphasis_control;
 };
 
-static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_ddi_translations[] = {
+static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_dp_ddi_trans[] = {
                                /* VS   pre-emp Non-trans mV    Pre-emph dB */
        { 0x7, 0x0, 0x00 },     /* 0    0       400mV           0 dB */
        { 0x5, 0x0, 0x03 },     /* 0    1       400mV           3.5 dB */
@@ -607,6 +607,20 @@ static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_ddi_translations[] = {
        { 0x0, 0x0, 0x00 },     /* 3    0       1200mV          0 dB HDMI default */
 };
 
+static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_hdmi_ddi_trans[] = {
+                               /* HDMI Preset  VS      Pre-emph */
+       { 0x7, 0x0, 0x0 },      /* 1            400mV   0dB */
+       { 0x6, 0x0, 0x0 },      /* 2            500mV   0dB */
+       { 0x4, 0x0, 0x0 },      /* 3            650mV   0dB */
+       { 0x2, 0x0, 0x0 },      /* 4            800mV   0dB */
+       { 0x0, 0x0, 0x0 },      /* 5            1000mV  0dB */
+       { 0x0, 0x0, 0x5 },      /* 6            Full    -1.5 dB */
+       { 0x0, 0x0, 0x6 },      /* 7            Full    -1.8 dB */
+       { 0x0, 0x0, 0x7 },      /* 8            Full    -2 dB */
+       { 0x0, 0x0, 0x8 },      /* 9            Full    -2.5 dB */
+       { 0x0, 0x0, 0xA },      /* 10           Full    -3 dB */
+};
+
 static const struct ddi_buf_trans *
 bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 {
@@ -898,7 +912,7 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por
                        icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
                                                0, &n_entries);
                else
-                       n_entries = ARRAY_SIZE(tgl_dkl_phy_ddi_translations);
+                       n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
                default_entry = n_entries - 1;
        } else if (INTEL_GEN(dev_priv) == 11) {
                if (intel_phy_is_combo(dev_priv, phy))
@@ -2371,7 +2385,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
                        icl_get_combo_buf_trans(dev_priv, encoder->type,
                                                intel_dp->link_rate, &n_entries);
                else
-                       n_entries = ARRAY_SIZE(tgl_dkl_phy_ddi_translations);
+                       n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
        } else if (INTEL_GEN(dev_priv) == 11) {
                if (intel_phy_is_combo(dev_priv, phy))
                        icl_get_combo_buf_trans(dev_priv, encoder->type,
@@ -2823,8 +2837,13 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
        const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
        u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
 
-       n_entries = ARRAY_SIZE(tgl_dkl_phy_ddi_translations);
-       ddi_translations = tgl_dkl_phy_ddi_translations;
+       if (encoder->type == INTEL_OUTPUT_HDMI) {
+               n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
+               ddi_translations = tgl_dkl_phy_hdmi_ddi_trans;
+       } else {
+               n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
+               ddi_translations = tgl_dkl_phy_dp_ddi_trans;
+       }
 
        if (level >= n_entries)
                level = n_entries - 1;
@@ -3967,6 +3986,7 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
        if (conn_state->content_protection ==
            DRM_MODE_CONTENT_PROTECTION_DESIRED)
                intel_hdcp_enable(to_intel_connector(conn_state->connector),
+                                 crtc_state->cpu_transcoder,
                                  (u8)conn_state->hdcp_content_type);
 }
 
@@ -4070,7 +4090,9 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
        if (conn_state->content_protection ==
            DRM_MODE_CONTENT_PROTECTION_DESIRED ||
            content_protection_type_changed)
-               intel_hdcp_enable(connector, (u8)conn_state->hdcp_content_type);
+               intel_hdcp_enable(connector,
+                                 crtc_state->cpu_transcoder,
+                                 (u8)conn_state->hdcp_content_type);
 }
 
 static void
index c61ac0c..b05b219 100644 (file)
@@ -2414,9 +2414,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 
        intel_psr_compute_config(intel_dp, pipe_config);
 
-       intel_hdcp_transcoder_config(intel_connector,
-                                    pipe_config->cpu_transcoder);
-
        return 0;
 }
 
@@ -5476,15 +5473,13 @@ static bool bxt_digital_port_connected(struct intel_encoder *encoder)
        return I915_READ(GEN8_DE_PORT_ISR) & bit;
 }
 
-static bool icl_combo_port_connected(struct drm_i915_private *dev_priv,
-                                    struct intel_digital_port *intel_dig_port)
+static bool intel_combo_phy_connected(struct drm_i915_private *dev_priv,
+                                     enum phy phy)
 {
-       enum port port = intel_dig_port->base.port;
-
-       if (HAS_PCH_MCC(dev_priv) && port == PORT_C)
+       if (HAS_PCH_MCC(dev_priv) && phy == PHY_C)
                return I915_READ(SDEISR) & SDE_TC_HOTPLUG_ICP(PORT_TC1);
 
-       return I915_READ(SDEISR) & SDE_DDI_HOTPLUG_ICP(port);
+       return I915_READ(SDEISR) & SDE_DDI_HOTPLUG_ICP(phy);
 }
 
 static bool icl_digital_port_connected(struct intel_encoder *encoder)
@@ -5494,7 +5489,7 @@ static bool icl_digital_port_connected(struct intel_encoder *encoder)
        enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
        if (intel_phy_is_combo(dev_priv, phy))
-               return icl_combo_port_connected(dev_priv, dig_port);
+               return intel_combo_phy_connected(dev_priv, phy);
        else if (intel_phy_is_tc(dev_priv, phy))
                return intel_tc_port_connected(dig_port);
        else
index 3111eca..2061663 100644 (file)
@@ -1284,7 +1284,7 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
                return 0;
 
        /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */
-       if (IS_GEMINILAKE(dev_priv))
+       if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
                return 0;
 
        if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
index f1f41ca..a448815 100644 (file)
@@ -1821,23 +1821,6 @@ enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
        }
 }
 
-void intel_hdcp_transcoder_config(struct intel_connector *connector,
-                                 enum transcoder cpu_transcoder)
-{
-       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct intel_hdcp *hdcp = &connector->hdcp;
-
-       if (!hdcp->shim)
-               return;
-
-       if (INTEL_GEN(dev_priv) >= 12) {
-               mutex_lock(&hdcp->mutex);
-               hdcp->cpu_transcoder = cpu_transcoder;
-               hdcp->port_data.fw_tc = intel_get_mei_fw_tc(cpu_transcoder);
-               mutex_unlock(&hdcp->mutex);
-       }
-}
-
 static inline int initialize_hdcp_port_data(struct intel_connector *connector,
                                            const struct intel_hdcp_shim *shim)
 {
@@ -1959,8 +1942,10 @@ int intel_hdcp_init(struct intel_connector *connector,
        return 0;
 }
 
-int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
+int intel_hdcp_enable(struct intel_connector *connector,
+                     enum transcoder cpu_transcoder, u8 content_type)
 {
+       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
        struct intel_hdcp *hdcp = &connector->hdcp;
        unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
        int ret = -EINVAL;
@@ -1972,6 +1957,11 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
        WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
        hdcp->content_type = content_type;
 
+       if (INTEL_GEN(dev_priv) >= 12) {
+               hdcp->cpu_transcoder = cpu_transcoder;
+               hdcp->port_data.fw_tc = intel_get_mei_fw_tc(cpu_transcoder);
+       }
+
        /*
         * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
         * is capable of HDCP2.2, it is preferred to use HDCP2.2.
index 41c1053..f3c3272 100644 (file)
@@ -21,11 +21,10 @@ enum transcoder;
 void intel_hdcp_atomic_check(struct drm_connector *connector,
                             struct drm_connector_state *old_state,
                             struct drm_connector_state *new_state);
-void intel_hdcp_transcoder_config(struct intel_connector *connector,
-                                 enum transcoder cpu_transcoder);
 int intel_hdcp_init(struct intel_connector *connector,
                    const struct intel_hdcp_shim *hdcp_shim);
-int intel_hdcp_enable(struct intel_connector *connector, u8 content_type);
+int intel_hdcp_enable(struct intel_connector *connector,
+                     enum transcoder cpu_transcoder, u8 content_type);
 int intel_hdcp_disable(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
index f6f5312..f56fffc 100644 (file)
@@ -2489,9 +2489,6 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
                return -EINVAL;
        }
 
-       intel_hdcp_transcoder_config(intel_hdmi->attached_connector,
-                                    pipe_config->cpu_transcoder);
-
        return 0;
 }
 
index e553ca8..337ba17 100644 (file)
@@ -368,7 +368,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
        if (!ce->timeline)
                return NULL;
 
-       rcu_read_lock();
+       mutex_lock(&ce->timeline->mutex);
        list_for_each_entry_reverse(rq, &ce->timeline->requests, link) {
                if (i915_request_completed(rq))
                        break;
@@ -378,7 +378,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
                if (engine)
                        break;
        }
-       rcu_read_unlock();
+       mutex_unlock(&ce->timeline->mutex);
 
        return engine;
 }
index ee9d2bc..ef7bc41 100644 (file)
@@ -310,10 +310,23 @@ int intel_context_prepare_remote_request(struct intel_context *ce,
        GEM_BUG_ON(rq->hw_context == ce);
 
        if (rcu_access_pointer(rq->timeline) != tl) { /* timeline sharing! */
-               err = mutex_lock_interruptible_nested(&tl->mutex,
-                                                     SINGLE_DEPTH_NESTING);
-               if (err)
-                       return err;
+               /*
+                * Ideally, we just want to insert our foreign fence as
+                * a barrier into the remove context, such that this operation
+                * occurs after all current operations in that context, and
+                * all future operations must occur after this.
+                *
+                * Currently, the timeline->last_request tracking is guarded
+                * by its mutex and so we must obtain that to atomically
+                * insert our barrier. However, since we already hold our
+                * timeline->mutex, we must be careful against potential
+                * inversion if we are the kernel_context as the remote context
+                * will itself poke at the kernel_context when it needs to
+                * unpin. Ergo, if already locked, we drop both locks and
+                * try again (through the magic of userspace repeating EAGAIN).
+                */
+               if (!mutex_trylock(&tl->mutex))
+                       return -EAGAIN;
 
                /* Queue this switch after current activity by this context. */
                err = i915_active_fence_set(&tl->last_request, rq);
index bc3b72b..01765a7 100644 (file)
@@ -100,9 +100,7 @@ execlists_num_ports(const struct intel_engine_execlists * const execlists)
 static inline struct i915_request *
 execlists_active(const struct intel_engine_execlists *execlists)
 {
-       GEM_BUG_ON(execlists->active - execlists->inflight >
-                  execlists_num_ports(execlists));
-       return READ_ONCE(*execlists->active);
+       return *READ_ONCE(execlists->active);
 }
 
 static inline void
index 5ca3ec9..813bd3a 100644 (file)
 
 #include "i915_drv.h"
 
-#include "gt/intel_gt.h"
-
+#include "intel_context.h"
 #include "intel_engine.h"
 #include "intel_engine_pm.h"
 #include "intel_engine_pool.h"
 #include "intel_engine_user.h"
-#include "intel_context.h"
+#include "intel_gt.h"
+#include "intel_gt_requests.h"
 #include "intel_lrc.h"
 #include "intel_reset.h"
 #include "intel_ring.h"
@@ -616,6 +616,7 @@ static int intel_engine_setup_common(struct intel_engine_cs *engine)
        intel_engine_init_execlists(engine);
        intel_engine_init_cmd_parser(engine);
        intel_engine_init__pm(engine);
+       intel_engine_init_retire(engine);
 
        intel_engine_pool_init(&engine->pool);
 
@@ -838,6 +839,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
 
        cleanup_status_page(engine);
 
+       intel_engine_fini_retire(engine);
        intel_engine_pool_fini(&engine->pool);
        intel_engine_fini_breadcrumbs(engine);
        intel_engine_cleanup_cmd_parser(engine);
index 874d826..c1dd0cd 100644 (file)
@@ -73,8 +73,42 @@ static inline void __timeline_mark_unlock(struct intel_context *ce,
 
 #endif /* !IS_ENABLED(CONFIG_LOCKDEP) */
 
+static void
+__queue_and_release_pm(struct i915_request *rq,
+                      struct intel_timeline *tl,
+                      struct intel_engine_cs *engine)
+{
+       struct intel_gt_timelines *timelines = &engine->gt->timelines;
+
+       GEM_TRACE("%s\n", engine->name);
+
+       /*
+        * We have to serialise all potential retirement paths with our
+        * submission, as we don't want to underflow either the
+        * engine->wakeref.counter or our timeline->active_count.
+        *
+        * Equally, we cannot allow a new submission to start until
+        * after we finish queueing, nor could we allow that submitter
+        * to retire us before we are ready!
+        */
+       spin_lock(&timelines->lock);
+
+       /* Let intel_gt_retire_requests() retire us (acquired under lock) */
+       if (!atomic_fetch_inc(&tl->active_count))
+               list_add_tail(&tl->link, &timelines->active_list);
+
+       /* Hand the request over to HW and so engine_retire() */
+       __i915_request_queue(rq, NULL);
+
+       /* Let new submissions commence (and maybe retire this timeline) */
+       __intel_wakeref_defer_park(&engine->wakeref);
+
+       spin_unlock(&timelines->lock);
+}
+
 static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 {
+       struct intel_context *ce = engine->kernel_context;
        struct i915_request *rq;
        unsigned long flags;
        bool result = true;
@@ -98,16 +132,31 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
         * This should hold true as we can only park the engine after
         * retiring the last request, thus all rings should be empty and
         * all timelines idle.
+        *
+        * For unlocking, there are 2 other parties and the GPU who have a
+        * stake here.
+        *
+        * A new gpu user will be waiting on the engine-pm to start their
+        * engine_unpark. New waiters are predicated on engine->wakeref.count
+        * and so intel_wakeref_defer_park() acts like a mutex_unlock of the
+        * engine->wakeref.
+        *
+        * The other party is intel_gt_retire_requests(), which is walking the
+        * list of active timelines looking for completions. Meanwhile as soon
+        * as we call __i915_request_queue(), the GPU may complete our request.
+        * Ergo, if we put ourselves on the timelines.active_list
+        * (se intel_timeline_enter()) before we increment the
+        * engine->wakeref.count, we may see the request completion and retire
+        * it causing an undeflow of the engine->wakeref.
         */
-       flags = __timeline_mark_lock(engine->kernel_context);
+       flags = __timeline_mark_lock(ce);
+       GEM_BUG_ON(atomic_read(&ce->timeline->active_count) < 0);
 
-       rq = __i915_request_create(engine->kernel_context, GFP_NOWAIT);
+       rq = __i915_request_create(ce, GFP_NOWAIT);
        if (IS_ERR(rq))
                /* Context switch failed, hope for the best! Maybe reset? */
                goto out_unlock;
 
-       intel_timeline_enter(i915_request_timeline(rq));
-
        /* Check again on the next retirement. */
        engine->wakeref_serial = engine->serial + 1;
        i915_request_add_active_barriers(rq);
@@ -116,13 +165,12 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
        rq->sched.attr.priority = I915_PRIORITY_BARRIER;
        __i915_request_commit(rq);
 
-       /* Release our exclusive hold on the engine */
-       __intel_wakeref_defer_park(&engine->wakeref);
-       __i915_request_queue(rq, NULL);
+       /* Expose ourselves to the world */
+       __queue_and_release_pm(rq, ce->timeline, engine);
 
        result = false;
 out_unlock:
-       __timeline_mark_unlock(engine->kernel_context, flags);
+       __timeline_mark_unlock(ce, flags);
        return result;
 }
 
@@ -177,7 +225,8 @@ static int __engine_park(struct intel_wakeref *wf)
 
        engine->execlists.no_priolist = false;
 
-       intel_gt_pm_put(engine->gt);
+       /* While gt calls i915_vma_parked(), we have to break the lock cycle */
+       intel_gt_pm_put_async(engine->gt);
        return 0;
 }
 
index 739c50f..24e2034 100644 (file)
@@ -31,6 +31,16 @@ static inline void intel_engine_pm_put(struct intel_engine_cs *engine)
        intel_wakeref_put(&engine->wakeref);
 }
 
+static inline void intel_engine_pm_put_async(struct intel_engine_cs *engine)
+{
+       intel_wakeref_put_async(&engine->wakeref);
+}
+
+static inline void intel_engine_pm_flush(struct intel_engine_cs *engine)
+{
+       intel_wakeref_unlock_wait(&engine->wakeref);
+}
+
 void intel_engine_init__pm(struct intel_engine_cs *engine);
 
 #endif /* INTEL_ENGINE_PM_H */
index 758f0e8..17f1f14 100644 (file)
@@ -451,6 +451,14 @@ struct intel_engine_cs {
 
        struct intel_engine_execlists execlists;
 
+       /*
+        * Keep track of completed timelines on this engine for early
+        * retirement with the goal of quickly enabling powersaving as
+        * soon as the engine is idle.
+        */
+       struct intel_timeline *retire;
+       struct work_struct retire_work;
+
        /* status_notifier: list of callbacks for context-switch changes */
        struct atomic_notifier_head context_status_notifier;
 
index 6187cdd..a459a42 100644 (file)
@@ -105,7 +105,6 @@ static int __gt_park(struct intel_wakeref *wf)
 static const struct intel_wakeref_ops wf_ops = {
        .get = __gt_unpark,
        .put = __gt_park,
-       .flags = INTEL_WAKEREF_PUT_ASYNC,
 };
 
 void intel_gt_pm_init_early(struct intel_gt *gt)
@@ -272,7 +271,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
 
 static suspend_state_t pm_suspend_target(void)
 {
-#if IS_ENABLED(CONFIG_PM_SLEEP)
+#if IS_ENABLED(CONFIG_SUSPEND) && IS_ENABLED(CONFIG_PM_SLEEP)
        return pm_suspend_target_state;
 #else
        return PM_SUSPEND_TO_IDLE;
index b3e1739..990efc2 100644 (file)
@@ -32,6 +32,11 @@ static inline void intel_gt_pm_put(struct intel_gt *gt)
        intel_wakeref_put(&gt->wakeref);
 }
 
+static inline void intel_gt_pm_put_async(struct intel_gt *gt)
+{
+       intel_wakeref_put_async(&gt->wakeref);
+}
+
 static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt)
 {
        return intel_wakeref_wait_for_idle(&gt->wakeref);
index 353809a..3dc13ec 100644 (file)
@@ -4,6 +4,8 @@
  * Copyright © 2019 Intel Corporation
  */
 
+#include <linux/workqueue.h>
+
 #include "i915_drv.h" /* for_each_engine() */
 #include "i915_request.h"
 #include "intel_gt.h"
@@ -29,6 +31,79 @@ static void flush_submission(struct intel_gt *gt)
                intel_engine_flush_submission(engine);
 }
 
+static void engine_retire(struct work_struct *work)
+{
+       struct intel_engine_cs *engine =
+               container_of(work, typeof(*engine), retire_work);
+       struct intel_timeline *tl = xchg(&engine->retire, NULL);
+
+       do {
+               struct intel_timeline *next = xchg(&tl->retire, NULL);
+
+               /*
+                * Our goal here is to retire _idle_ timelines as soon as
+                * possible (as they are idle, we do not expect userspace
+                * to be cleaning up anytime soon).
+                *
+                * If the timeline is currently locked, either it is being
+                * retired elsewhere or about to be!
+                */
+               if (mutex_trylock(&tl->mutex)) {
+                       retire_requests(tl);
+                       mutex_unlock(&tl->mutex);
+               }
+               intel_timeline_put(tl);
+
+               GEM_BUG_ON(!next);
+               tl = ptr_mask_bits(next, 1);
+       } while (tl);
+}
+
+static bool add_retire(struct intel_engine_cs *engine,
+                      struct intel_timeline *tl)
+{
+       struct intel_timeline *first;
+
+       /*
+        * We open-code a llist here to include the additional tag [BIT(0)]
+        * so that we know when the timeline is already on a
+        * retirement queue: either this engine or another.
+        *
+        * However, we rely on that a timeline can only be active on a single
+        * engine at any one time and that add_retire() is called before the
+        * engine releases the timeline and transferred to another to retire.
+        */
+
+       if (READ_ONCE(tl->retire)) /* already queued */
+               return false;
+
+       intel_timeline_get(tl);
+       first = READ_ONCE(engine->retire);
+       do
+               tl->retire = ptr_pack_bits(first, 1, 1);
+       while (!try_cmpxchg(&engine->retire, &first, tl));
+
+       return !first;
+}
+
+void intel_engine_add_retire(struct intel_engine_cs *engine,
+                            struct intel_timeline *tl)
+{
+       if (add_retire(engine, tl))
+               schedule_work(&engine->retire_work);
+}
+
+void intel_engine_init_retire(struct intel_engine_cs *engine)
+{
+       INIT_WORK(&engine->retire_work, engine_retire);
+}
+
+void intel_engine_fini_retire(struct intel_engine_cs *engine)
+{
+       flush_work(&engine->retire_work);
+       GEM_BUG_ON(engine->retire);
+}
+
 long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
 {
        struct intel_gt_timelines *timelines = &gt->timelines;
@@ -52,8 +127,8 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
                }
 
                intel_timeline_get(tl);
-               GEM_BUG_ON(!tl->active_count);
-               tl->active_count++; /* pin the list element */
+               GEM_BUG_ON(!atomic_read(&tl->active_count));
+               atomic_inc(&tl->active_count); /* pin the list element */
                spin_unlock_irqrestore(&timelines->lock, flags);
 
                if (timeout > 0) {
@@ -74,7 +149,7 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
 
                /* Resume iteration after dropping lock */
                list_safe_reset_next(tl, tn, link);
-               if (!--tl->active_count)
+               if (atomic_dec_and_test(&tl->active_count))
                        list_del(&tl->link);
                else
                        active_count += !!rcu_access_pointer(tl->last_request.fence);
@@ -83,7 +158,7 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
 
                /* Defer the final release to after the spinlock */
                if (refcount_dec_and_test(&tl->kref.refcount)) {
-                       GEM_BUG_ON(tl->active_count);
+                       GEM_BUG_ON(atomic_read(&tl->active_count));
                        list_add(&tl->link, &free);
                }
        }
index bd31cbc..d626fb1 100644 (file)
@@ -7,7 +7,9 @@
 #ifndef INTEL_GT_REQUESTS_H
 #define INTEL_GT_REQUESTS_H
 
+struct intel_engine_cs;
 struct intel_gt;
+struct intel_timeline;
 
 long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout);
 static inline void intel_gt_retire_requests(struct intel_gt *gt)
@@ -15,6 +17,11 @@ static inline void intel_gt_retire_requests(struct intel_gt *gt)
        intel_gt_retire_requests_timeout(gt, 0);
 }
 
+void intel_engine_init_retire(struct intel_engine_cs *engine);
+void intel_engine_add_retire(struct intel_engine_cs *engine,
+                            struct intel_timeline *tl);
+void intel_engine_fini_retire(struct intel_engine_cs *engine);
+
 int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout);
 
 void intel_gt_init_requests(struct intel_gt *gt);
index 0ac3b26..75dd0e0 100644 (file)
 #include "intel_engine_pm.h"
 #include "intel_gt.h"
 #include "intel_gt_pm.h"
+#include "intel_gt_requests.h"
 #include "intel_lrc_reg.h"
 #include "intel_mocs.h"
 #include "intel_reset.h"
@@ -844,12 +845,6 @@ static const u8 *reg_offsets(const struct intel_engine_cs *engine)
        }
 }
 
-static void unwind_wa_tail(struct i915_request *rq)
-{
-       rq->tail = intel_ring_wrap(rq->ring, rq->wa_tail - WA_TAIL_BYTES);
-       assert_ring_tail_valid(rq->ring, rq->tail);
-}
-
 static struct i915_request *
 __unwind_incomplete_requests(struct intel_engine_cs *engine)
 {
@@ -862,12 +857,10 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
        list_for_each_entry_safe_reverse(rq, rn,
                                         &engine->active.requests,
                                         sched.link) {
-
                if (i915_request_completed(rq))
                        continue; /* XXX */
 
                __i915_request_unsubmit(rq);
-               unwind_wa_tail(rq);
 
                /*
                 * Push the request back into the queue for later resubmission.
@@ -1115,9 +1108,17 @@ __execlists_schedule_out(struct i915_request *rq,
         * refrain from doing non-trivial work here.
         */
 
+       /*
+        * If we have just completed this context, the engine may now be
+        * idle and we want to re-enter powersaving.
+        */
+       if (list_is_last(&rq->link, &ce->timeline->requests) &&
+           i915_request_completed(rq))
+               intel_engine_add_retire(engine, ce->timeline);
+
        intel_engine_context_out(engine);
        execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
-       intel_gt_pm_put(engine->gt);
+       intel_gt_pm_put_async(engine->gt);
 
        /*
         * If this is part of a virtual engine, its next request may
@@ -1152,13 +1153,29 @@ execlists_schedule_out(struct i915_request *rq)
        i915_request_put(rq);
 }
 
-static u64 execlists_update_context(const struct i915_request *rq)
+static u64 execlists_update_context(struct i915_request *rq)
 {
        struct intel_context *ce = rq->hw_context;
-       u64 desc;
+       u64 desc = ce->lrc_desc;
+       u32 tail;
 
-       ce->lrc_reg_state[CTX_RING_TAIL] =
-               intel_ring_set_tail(rq->ring, rq->tail);
+       /*
+        * WaIdleLiteRestore:bdw,skl
+        *
+        * We should never submit the context with the same RING_TAIL twice
+        * just in case we submit an empty ring, which confuses the HW.
+        *
+        * We append a couple of NOOPs (gen8_emit_wa_tail) after the end of
+        * the normal request to be able to always advance the RING_TAIL on
+        * subsequent resubmissions (for lite restore). Should that fail us,
+        * and we try and submit the same tail again, force the context
+        * reload.
+        */
+       tail = intel_ring_set_tail(rq->ring, rq->tail);
+       if (unlikely(ce->lrc_reg_state[CTX_RING_TAIL] == tail))
+               desc |= CTX_DESC_FORCE_RESTORE;
+       ce->lrc_reg_state[CTX_RING_TAIL] = tail;
+       rq->tail = rq->wa_tail;
 
        /*
         * Make sure the context image is complete before we submit it to HW.
@@ -1177,13 +1194,11 @@ static u64 execlists_update_context(const struct i915_request *rq)
         */
        mb();
 
-       desc = ce->lrc_desc;
-       ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE;
-
        /* Wa_1607138340:tgl */
        if (IS_TGL_REVID(rq->i915, TGL_REVID_A0, TGL_REVID_A0))
                desc |= CTX_DESC_FORCE_RESTORE;
 
+       ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE;
        return desc;
 }
 
@@ -1694,16 +1709,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 
                                return;
                        }
-
-                       /*
-                        * WaIdleLiteRestore:bdw,skl
-                        * Apply the wa NOOPs to prevent
-                        * ring:HEAD == rq:TAIL as we resubmit the
-                        * request. See gen8_emit_fini_breadcrumb() for
-                        * where we prepare the padding after the
-                        * end of the request.
-                        */
-                       last->tail = last->wa_tail;
                }
        }
 
@@ -1937,16 +1942,17 @@ skip_submit:
 static void
 cancel_port_requests(struct intel_engine_execlists * const execlists)
 {
-       struct i915_request * const *port, *rq;
+       struct i915_request * const *port;
 
-       for (port = execlists->pending; (rq = *port); port++)
-               execlists_schedule_out(rq);
+       for (port = execlists->pending; *port; port++)
+               execlists_schedule_out(*port);
        memset(execlists->pending, 0, sizeof(execlists->pending));
 
-       for (port = execlists->active; (rq = *port); port++)
-               execlists_schedule_out(rq);
-       execlists->active =
-               memset(execlists->inflight, 0, sizeof(execlists->inflight));
+       /* Mark the end of active before we overwrite *active */
+       for (port = xchg(&execlists->active, execlists->pending); *port; port++)
+               execlists_schedule_out(*port);
+       WRITE_ONCE(execlists->active,
+                  memset(execlists->inflight, 0, sizeof(execlists->inflight)));
 }
 
 static inline void
@@ -2099,23 +2105,27 @@ static void process_csb(struct intel_engine_cs *engine)
                else
                        promote = gen8_csb_parse(execlists, buf + 2 * head);
                if (promote) {
+                       struct i915_request * const *old = execlists->active;
+
+                       /* Point active to the new ELSP; prevent overwriting */
+                       WRITE_ONCE(execlists->active, execlists->pending);
+                       set_timeslice(engine);
+
                        if (!inject_preempt_hang(execlists))
                                ring_set_paused(engine, 0);
 
                        /* cancel old inflight, prepare for switch */
-                       trace_ports(execlists, "preempted", execlists->active);
-                       while (*execlists->active)
-                               execlists_schedule_out(*execlists->active++);
+                       trace_ports(execlists, "preempted", old);
+                       while (*old)
+                               execlists_schedule_out(*old++);
 
                        /* switch pending to inflight */
                        GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
-                       execlists->active =
-                               memcpy(execlists->inflight,
-                                      execlists->pending,
-                                      execlists_num_ports(execlists) *
-                                      sizeof(*execlists->pending));
-
-                       set_timeslice(engine);
+                       WRITE_ONCE(execlists->active,
+                                  memcpy(execlists->inflight,
+                                         execlists->pending,
+                                         execlists_num_ports(execlists) *
+                                         sizeof(*execlists->pending)));
 
                        WRITE_ONCE(execlists->pending[0], NULL);
                } else {
@@ -4106,17 +4116,18 @@ static void virtual_context_destroy(struct kref *kref)
        for (n = 0; n < ve->num_siblings; n++) {
                struct intel_engine_cs *sibling = ve->siblings[n];
                struct rb_node *node = &ve->nodes[sibling->id].rb;
+               unsigned long flags;
 
                if (RB_EMPTY_NODE(node))
                        continue;
 
-               spin_lock_irq(&sibling->active.lock);
+               spin_lock_irqsave(&sibling->active.lock, flags);
 
                /* Detachment is lazily performed in the execlists tasklet */
                if (!RB_EMPTY_NODE(node))
                        rb_erase_cached(node, &sibling->execlists.virtual);
 
-               spin_unlock_irq(&sibling->active.lock);
+               spin_unlock_irqrestore(&sibling->active.lock, flags);
        }
        GEM_BUG_ON(__tasklet_is_scheduled(&ve->base.execlists.tasklet));
 
index f03e000..c97423a 100644 (file)
@@ -1114,7 +1114,7 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg)
 out:
        intel_engine_cancel_stop_cs(engine);
        reset_finish_engine(engine);
-       intel_engine_pm_put(engine);
+       intel_engine_pm_put_async(engine);
        return ret;
 }
 
index ece2050..374b28f 100644 (file)
@@ -57,9 +57,10 @@ int intel_ring_pin(struct intel_ring *ring)
 
        i915_vma_make_unshrinkable(vma);
 
-       GEM_BUG_ON(ring->vaddr);
-       ring->vaddr = addr;
+       /* Discard any unused bytes beyond that submitted to hw. */
+       intel_ring_reset(ring, ring->emit);
 
+       ring->vaddr = addr;
        return 0;
 
 err_ring:
@@ -85,20 +86,14 @@ void intel_ring_unpin(struct intel_ring *ring)
        if (!atomic_dec_and_test(&ring->pin_count))
                return;
 
-       /* Discard any unused bytes beyond that submitted to hw. */
-       intel_ring_reset(ring, ring->emit);
-
        i915_vma_unset_ggtt_write(vma);
        if (i915_vma_is_map_and_fenceable(vma))
                i915_vma_unpin_iomap(vma);
        else
                i915_gem_object_unpin_map(vma->obj);
 
-       GEM_BUG_ON(!ring->vaddr);
-       ring->vaddr = NULL;
-
-       i915_vma_unpin(vma);
        i915_vma_make_purgeable(vma);
+       i915_vma_unpin(vma);
 }
 
 static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
index 14ad10a..649798c 100644 (file)
@@ -282,6 +282,7 @@ void intel_timeline_fini(struct intel_timeline *timeline)
 {
        GEM_BUG_ON(atomic_read(&timeline->pin_count));
        GEM_BUG_ON(!list_empty(&timeline->requests));
+       GEM_BUG_ON(timeline->retire);
 
        if (timeline->hwsp_cacheline)
                cacheline_free(timeline->hwsp_cacheline);
@@ -339,15 +340,33 @@ void intel_timeline_enter(struct intel_timeline *tl)
        struct intel_gt_timelines *timelines = &tl->gt->timelines;
        unsigned long flags;
 
+       /*
+        * Pretend we are serialised by the timeline->mutex.
+        *
+        * While generally true, there are a few exceptions to the rule
+        * for the engine->kernel_context being used to manage power
+        * transitions. As the engine_park may be called from under any
+        * timeline, it uses the power mutex as a global serialisation
+        * lock to prevent any other request entering its timeline.
+        *
+        * The rule is generally tl->mutex, otherwise engine->wakeref.mutex.
+        *
+        * However, intel_gt_retire_request() does not know which engine
+        * it is retiring along and so cannot partake in the engine-pm
+        * barrier, and there we use the tl->active_count as a means to
+        * pin the timeline in the active_list while the locks are dropped.
+        * Ergo, as that is outside of the engine-pm barrier, we need to
+        * use atomic to manipulate tl->active_count.
+        */
        lockdep_assert_held(&tl->mutex);
-
        GEM_BUG_ON(!atomic_read(&tl->pin_count));
-       if (tl->active_count++)
+
+       if (atomic_add_unless(&tl->active_count, 1, 0))
                return;
-       GEM_BUG_ON(!tl->active_count); /* overflow? */
 
        spin_lock_irqsave(&timelines->lock, flags);
-       list_add(&tl->link, &timelines->active_list);
+       if (!atomic_fetch_inc(&tl->active_count))
+               list_add_tail(&tl->link, &timelines->active_list);
        spin_unlock_irqrestore(&timelines->lock, flags);
 }
 
@@ -356,14 +375,16 @@ void intel_timeline_exit(struct intel_timeline *tl)
        struct intel_gt_timelines *timelines = &tl->gt->timelines;
        unsigned long flags;
 
+       /* See intel_timeline_enter() */
        lockdep_assert_held(&tl->mutex);
 
-       GEM_BUG_ON(!tl->active_count);
-       if (--tl->active_count)
+       GEM_BUG_ON(!atomic_read(&tl->active_count));
+       if (atomic_add_unless(&tl->active_count, -1, 1))
                return;
 
        spin_lock_irqsave(&timelines->lock, flags);
-       list_del(&tl->link);
+       if (atomic_dec_and_test(&tl->active_count))
+               list_del(&tl->link);
        spin_unlock_irqrestore(&timelines->lock, flags);
 
        /*
index 98d9ee1..aaf15cb 100644 (file)
@@ -42,7 +42,7 @@ struct intel_timeline {
         * from the intel_context caller plus internal atomicity.
         */
        atomic_t pin_count;
-       unsigned int active_count;
+       atomic_t active_count;
 
        const u32 *hwsp_seqno;
        struct i915_vma *hwsp_ggtt;
@@ -66,6 +66,9 @@ struct intel_timeline {
         */
        struct i915_active_fence last_request;
 
+       /** A chain of completed timelines ready for early retirement. */
+       struct intel_timeline *retire;
+
        /**
         * We track the most recent seqno that we wait on in every context so
         * that we only have to emit a new await and dependency on a more
index 20b9c83..cbf6b07 100644 (file)
@@ -51,11 +51,12 @@ static int live_engine_pm(void *arg)
                                pr_err("intel_engine_pm_get_if_awake(%s) failed under %s\n",
                                       engine->name, p->name);
                        else
-                               intel_engine_pm_put(engine);
-                       intel_engine_pm_put(engine);
+                               intel_engine_pm_put_async(engine);
+                       intel_engine_pm_put_async(engine);
                        p->critical_section_end();
 
-                       /* engine wakeref is sync (instant) */
+                       intel_engine_pm_flush(engine);
+
                        if (intel_engine_pm_is_awake(engine)) {
                                pr_err("%s is still awake after flushing pm\n",
                                       engine->name);
index 6a3ac8c..21a176c 100644 (file)
@@ -1599,9 +1599,9 @@ static int cmd_handler_mi_op_2f(struct parser_exec_state *s)
        if (!(cmd_val(s, 0) & (1 << 22)))
                return ret;
 
-       /* check if QWORD */
-       if (DWORD_FIELD(0, 20, 19) == 1)
-               valid_len += 8;
+       /* check inline data */
+       if (cmd_val(s, 0) & BIT(18))
+               valid_len = CMD_LEN(9);
        ret = gvt_check_valid_cmd_length(cmd_length(s),
                        valid_len);
        if (ret)
index bd12af3..bb9fe6b 100644 (file)
@@ -460,6 +460,7 @@ static int pipeconf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 static i915_reg_t force_nonpriv_white_list[] = {
        GEN9_CS_DEBUG_MODE1, //_MMIO(0x20ec)
        GEN9_CTX_PREEMPT_REG,//_MMIO(0x2248)
+       PS_INVOCATION_COUNT,//_MMIO(0x2348)
        GEN8_CS_CHICKEN1,//_MMIO(0x2580)
        _MMIO(0x2690),
        _MMIO(0x2694),
@@ -508,7 +509,7 @@ static inline bool in_whitelist(unsigned int reg)
 static int force_nonpriv_write(struct intel_vgpu *vgpu,
        unsigned int offset, void *p_data, unsigned int bytes)
 {
-       u32 reg_nonpriv = *(u32 *)p_data;
+       u32 reg_nonpriv = (*(u32 *)p_data) & REG_GENMASK(25, 2);
        int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
        u32 ring_base;
        struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
@@ -528,7 +529,7 @@ static int force_nonpriv_write(struct intel_vgpu *vgpu,
                        bytes);
        } else
                gvt_err("vgpu(%d) Invalid FORCE_NONPRIV write %x at offset %x\n",
-                       vgpu->id, reg_nonpriv, offset);
+                       vgpu->id, *(u32 *)p_data, offset);
 
        return 0;
 }
index 3c424cb..a19e7d8 100644 (file)
@@ -672,12 +672,13 @@ void i915_active_acquire_barrier(struct i915_active *ref)
         * populated by i915_request_add_active_barriers() to point to the
         * request that will eventually release them.
         */
-       spin_lock_irqsave_nested(&ref->tree_lock, flags, SINGLE_DEPTH_NESTING);
        llist_for_each_safe(pos, next, take_preallocated_barriers(ref)) {
                struct active_node *node = barrier_from_ll(pos);
                struct intel_engine_cs *engine = barrier_to_engine(node);
                struct rb_node **p, *parent;
 
+               spin_lock_irqsave_nested(&ref->tree_lock, flags,
+                                        SINGLE_DEPTH_NESTING);
                parent = NULL;
                p = &ref->tree.rb_node;
                while (*p) {
@@ -693,12 +694,12 @@ void i915_active_acquire_barrier(struct i915_active *ref)
                }
                rb_link_node(&node->node, parent, p);
                rb_insert_color(&node->node, &ref->tree);
+               spin_unlock_irqrestore(&ref->tree_lock, flags);
 
                GEM_BUG_ON(!intel_engine_pm_is_awake(engine));
                llist_add(barrier_to_ll(node), &engine->barrier_tasks);
                intel_engine_pm_put(engine);
        }
-       spin_unlock_irqrestore(&ref->tree_lock, flags);
 }
 
 void i915_request_add_active_barriers(struct i915_request *rq)
index b9eb6b3..d034fa4 100644 (file)
@@ -45,6 +45,7 @@
 #include "gem/i915_gem_context.h"
 #include "gem/i915_gem_ioctls.h"
 #include "gem/i915_gem_pm.h"
+#include "gt/intel_context.h"
 #include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
@@ -1053,6 +1054,18 @@ out:
        return err;
 }
 
+static int __intel_context_flush_retire(struct intel_context *ce)
+{
+       struct intel_timeline *tl;
+
+       tl = intel_context_timeline_lock(ce);
+       if (IS_ERR(tl))
+               return PTR_ERR(tl);
+
+       intel_context_timeline_unlock(tl);
+       return 0;
+}
+
 static int __intel_engines_record_defaults(struct intel_gt *gt)
 {
        struct i915_request *requests[I915_NUM_ENGINES] = {};
@@ -1121,13 +1134,20 @@ err_rq:
                if (!rq)
                        continue;
 
-               /* We want to be able to unbind the state from the GGTT */
-               GEM_BUG_ON(intel_context_is_pinned(rq->hw_context));
-
+               GEM_BUG_ON(!test_bit(CONTEXT_ALLOC_BIT,
+                                    &rq->hw_context->flags));
                state = rq->hw_context->state;
                if (!state)
                        continue;
 
+               /* Serialise with retirement on another CPU */
+               err = __intel_context_flush_retire(rq->hw_context);
+               if (err)
+                       goto out;
+
+               /* We want to be able to unbind the state from the GGTT */
+               GEM_BUG_ON(intel_context_is_pinned(rq->hw_context));
+
                /*
                 * As we will hold a reference to the logical state, it will
                 * not be torn down with the context, and importantly the
index 65d7c2e..2ae14bc 100644 (file)
@@ -2078,20 +2078,12 @@ gen8_update_reg_state_unlocked(const struct intel_context *ce,
        u32 *reg_state = ce->lrc_reg_state;
        int i;
 
-       if (IS_GEN(stream->perf->i915, 12)) {
-               u32 format = stream->oa_buffer.format;
+       reg_state[ctx_oactxctrl + 1] =
+               (stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
+               (stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
+               GEN8_OA_COUNTER_RESUME;
 
-               reg_state[ctx_oactxctrl + 1] =
-                       (format << GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT) |
-                       (stream->oa_config ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0);
-       } else {
-               reg_state[ctx_oactxctrl + 1] =
-                       (stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
-                       (stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
-                       GEN8_OA_COUNTER_RESUME;
-       }
-
-       for (i = 0; !!ctx_flexeu0 && i < ARRAY_SIZE(flex_regs); i++)
+       for (i = 0; i < ARRAY_SIZE(flex_regs); i++)
                reg_state[ctx_flexeu0 + i * 2 + 1] =
                        oa_config_flex_reg(stream->oa_config, flex_regs[i]);
 
@@ -2224,34 +2216,51 @@ static int gen8_configure_context(struct i915_gem_context *ctx,
        return err;
 }
 
-static int gen12_emit_oar_config(struct intel_context *ce, bool enable)
+static int gen12_configure_oar_context(struct i915_perf_stream *stream, bool enable)
 {
-       struct i915_request *rq;
-       u32 *cs;
-       int err = 0;
-
-       rq = i915_request_create(ce);
-       if (IS_ERR(rq))
-               return PTR_ERR(rq);
-
-       cs = intel_ring_begin(rq, 4);
-       if (IS_ERR(cs)) {
-               err = PTR_ERR(cs);
-               goto out;
-       }
-
-       *cs++ = MI_LOAD_REGISTER_IMM(1);
-       *cs++ = i915_mmio_reg_offset(RING_CONTEXT_CONTROL(ce->engine->mmio_base));
-       *cs++ = _MASKED_FIELD(GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE,
-                             enable ? GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE : 0);
-       *cs++ = MI_NOOP;
+       int err;
+       struct intel_context *ce = stream->pinned_ctx;
+       u32 format = stream->oa_buffer.format;
+       struct flex regs_context[] = {
+               {
+                       GEN8_OACTXCONTROL,
+                       stream->perf->ctx_oactxctrl_offset + 1,
+                       enable ? GEN8_OA_COUNTER_RESUME : 0,
+               },
+       };
+       /* Offsets in regs_lri are not used since this configuration is only
+        * applied using LRI. Initialize the correct offsets for posterity.
+        */
+#define GEN12_OAR_OACONTROL_OFFSET 0x5B0
+       struct flex regs_lri[] = {
+               {
+                       GEN12_OAR_OACONTROL,
+                       GEN12_OAR_OACONTROL_OFFSET + 1,
+                       (format << GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT) |
+                       (enable ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0)
+               },
+               {
+                       RING_CONTEXT_CONTROL(ce->engine->mmio_base),
+                       CTX_CONTEXT_CONTROL,
+                       _MASKED_FIELD(GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE,
+                                     enable ?
+                                     GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE :
+                                     0)
+               },
+       };
 
-       intel_ring_advance(rq, cs);
+       /* Modify the context image of pinned context with regs_context*/
+       err = intel_context_lock_pinned(ce);
+       if (err)
+               return err;
 
-out:
-       i915_request_add(rq);
+       err = gen8_modify_context(ce, regs_context, ARRAY_SIZE(regs_context));
+       intel_context_unlock_pinned(ce);
+       if (err)
+               return err;
 
-       return err;
+       /* Apply regs_lri using LRI with pinned context */
+       return gen8_modify_self(ce, regs_lri, ARRAY_SIZE(regs_lri));
 }
 
 /*
@@ -2277,53 +2286,16 @@ out:
  *   per-context OA state.
  *
  * Note: it's only the RCS/Render context that has any OA state.
+ * Note: the first flex register passed must always be R_PWR_CLK_STATE
  */
-static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
-                                     const struct i915_oa_config *oa_config)
+static int oa_configure_all_contexts(struct i915_perf_stream *stream,
+                                    struct flex *regs,
+                                    size_t num_regs)
 {
        struct drm_i915_private *i915 = stream->perf->i915;
-       /* The MMIO offsets for Flex EU registers aren't contiguous */
-       const u32 ctx_flexeu0 = stream->perf->ctx_flexeu0_offset;
-#define ctx_flexeuN(N) (ctx_flexeu0 + 2 * (N) + 1)
-       struct flex regs[] = {
-               {
-                       GEN8_R_PWR_CLK_STATE,
-                       CTX_R_PWR_CLK_STATE,
-               },
-               {
-                       IS_GEN(i915, 12) ?
-                       GEN12_OAR_OACONTROL : GEN8_OACTXCONTROL,
-                       stream->perf->ctx_oactxctrl_offset + 1,
-               },
-               { EU_PERF_CNTL0, ctx_flexeuN(0) },
-               { EU_PERF_CNTL1, ctx_flexeuN(1) },
-               { EU_PERF_CNTL2, ctx_flexeuN(2) },
-               { EU_PERF_CNTL3, ctx_flexeuN(3) },
-               { EU_PERF_CNTL4, ctx_flexeuN(4) },
-               { EU_PERF_CNTL5, ctx_flexeuN(5) },
-               { EU_PERF_CNTL6, ctx_flexeuN(6) },
-       };
-#undef ctx_flexeuN
        struct intel_engine_cs *engine;
        struct i915_gem_context *ctx, *cn;
-       size_t array_size = IS_GEN(i915, 12) ? 2 : ARRAY_SIZE(regs);
-       int i, err;
-
-       if (IS_GEN(i915, 12)) {
-               u32 format = stream->oa_buffer.format;
-
-               regs[1].value =
-                       (format << GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT) |
-                       (oa_config ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0);
-       } else {
-               regs[1].value =
-                       (stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
-                       (stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
-                       GEN8_OA_COUNTER_RESUME;
-       }
-
-       for (i = 2; !!ctx_flexeu0 && i < array_size; i++)
-               regs[i].value = oa_config_flex_reg(oa_config, regs[i].reg);
+       int err;
 
        lockdep_assert_held(&stream->perf->lock);
 
@@ -2353,7 +2325,7 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
 
                spin_unlock(&i915->gem.contexts.lock);
 
-               err = gen8_configure_context(ctx, regs, array_size);
+               err = gen8_configure_context(ctx, regs, num_regs);
                if (err) {
                        i915_gem_context_put(ctx);
                        return err;
@@ -2378,7 +2350,7 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
 
                regs[0].value = intel_sseu_make_rpcs(i915, &ce->sseu);
 
-               err = gen8_modify_self(ce, regs, array_size);
+               err = gen8_modify_self(ce, regs, num_regs);
                if (err)
                        return err;
        }
@@ -2386,6 +2358,56 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
        return 0;
 }
 
+static int gen12_configure_all_contexts(struct i915_perf_stream *stream,
+                                       const struct i915_oa_config *oa_config)
+{
+       struct flex regs[] = {
+               {
+                       GEN8_R_PWR_CLK_STATE,
+                       CTX_R_PWR_CLK_STATE,
+               },
+       };
+
+       return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs));
+}
+
+static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
+                                     const struct i915_oa_config *oa_config)
+{
+       /* The MMIO offsets for Flex EU registers aren't contiguous */
+       const u32 ctx_flexeu0 = stream->perf->ctx_flexeu0_offset;
+#define ctx_flexeuN(N) (ctx_flexeu0 + 2 * (N) + 1)
+       struct flex regs[] = {
+               {
+                       GEN8_R_PWR_CLK_STATE,
+                       CTX_R_PWR_CLK_STATE,
+               },
+               {
+                       GEN8_OACTXCONTROL,
+                       stream->perf->ctx_oactxctrl_offset + 1,
+               },
+               { EU_PERF_CNTL0, ctx_flexeuN(0) },
+               { EU_PERF_CNTL1, ctx_flexeuN(1) },
+               { EU_PERF_CNTL2, ctx_flexeuN(2) },
+               { EU_PERF_CNTL3, ctx_flexeuN(3) },
+               { EU_PERF_CNTL4, ctx_flexeuN(4) },
+               { EU_PERF_CNTL5, ctx_flexeuN(5) },
+               { EU_PERF_CNTL6, ctx_flexeuN(6) },
+       };
+#undef ctx_flexeuN
+       int i;
+
+       regs[1].value =
+               (stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
+               (stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
+               GEN8_OA_COUNTER_RESUME;
+
+       for (i = 2; i < ARRAY_SIZE(regs); i++)
+               regs[i].value = oa_config_flex_reg(oa_config, regs[i].reg);
+
+       return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs));
+}
+
 static int gen8_enable_metric_set(struct i915_perf_stream *stream)
 {
        struct intel_uncore *uncore = stream->uncore;
@@ -2464,7 +2486,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream)
         * to make sure all slices/subslices are ON before writing to NOA
         * registers.
         */
-       ret = lrc_configure_all_contexts(stream, oa_config);
+       ret = gen12_configure_all_contexts(stream, oa_config);
        if (ret)
                return ret;
 
@@ -2474,8 +2496,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream)
         * requested this.
         */
        if (stream->ctx) {
-               ret = gen12_emit_oar_config(stream->pinned_ctx,
-                                           oa_config != NULL);
+               ret = gen12_configure_oar_context(stream, true);
                if (ret)
                        return ret;
        }
@@ -2509,11 +2530,11 @@ static void gen12_disable_metric_set(struct i915_perf_stream *stream)
        struct intel_uncore *uncore = stream->uncore;
 
        /* Reset all contexts' slices/subslices configurations. */
-       lrc_configure_all_contexts(stream, NULL);
+       gen12_configure_all_contexts(stream, NULL);
 
        /* disable the context save/restore or OAR counters */
        if (stream->ctx)
-               gen12_emit_oar_config(stream->pinned_ctx, false);
+               gen12_configure_oar_context(stream, false);
 
        /* Make sure we disable noa to save power. */
        intel_uncore_rmw(uncore, RPM_CONFIG1, GEN10_GT_NOA_ENABLE, 0);
@@ -2713,7 +2734,8 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
                return -EINVAL;
        }
 
-       if (!(props->sample_flags & SAMPLE_OA_REPORT)) {
+       if (!(props->sample_flags & SAMPLE_OA_REPORT) &&
+           (INTEL_GEN(perf->i915) < 12 || !stream->ctx)) {
                DRM_DEBUG("Only OA report sampling supported\n");
                return -EINVAL;
        }
@@ -2745,7 +2767,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
 
        format_size = perf->oa_formats[props->oa_format].size;
 
-       stream->sample_flags |= SAMPLE_OA_REPORT;
+       stream->sample_flags = props->sample_flags;
        stream->sample_size += format_size;
 
        stream->oa_buffer.format_size = format_size;
@@ -2854,7 +2876,11 @@ void i915_oa_init_reg_state(const struct intel_context *ce,
                return;
 
        stream = engine->i915->perf.exclusive_stream;
-       if (stream)
+       /*
+        * For gen12, only CTX_R_PWR_CLK_STATE needs update, but the caller
+        * is already doing that, so nothing to be done for gen12 here.
+        */
+       if (stream && INTEL_GEN(stream->perf->i915) < 12)
                gen8_update_reg_state_unlocked(ce, stream);
 }
 
index 0d40dcc..2814218 100644 (file)
@@ -190,7 +190,7 @@ static u64 get_rc6(struct intel_gt *gt)
        val = 0;
        if (intel_gt_pm_get_if_awake(gt)) {
                val = __get_rc6(gt);
-               intel_gt_pm_put(gt);
+               intel_gt_pm_put_async(gt);
        }
 
        spin_lock_irqsave(&pmu->lock, flags);
@@ -343,7 +343,7 @@ engines_sample(struct intel_gt *gt, unsigned int period_ns)
 
 skip:
                spin_unlock_irqrestore(&engine->uncore->lock, flags);
-               intel_engine_pm_put(engine);
+               intel_engine_pm_put_async(engine);
        }
 }
 
@@ -368,7 +368,7 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns)
                if (intel_gt_pm_get_if_awake(gt)) {
                        val = intel_uncore_read_notrace(uncore, GEN6_RPSTAT1);
                        val = intel_get_cagf(rps, val);
-                       intel_gt_pm_put(gt);
+                       intel_gt_pm_put_async(gt);
                }
 
                add_sample_mult(&pmu->sample[__I915_SAMPLE_FREQ_ACT],
index c27cfef..ef25ce6 100644 (file)
@@ -103,15 +103,18 @@ query_engine_info(struct drm_i915_private *i915,
        struct drm_i915_engine_info __user *info_ptr;
        struct drm_i915_query_engine_info query;
        struct drm_i915_engine_info info = { };
+       unsigned int num_uabi_engines = 0;
        struct intel_engine_cs *engine;
        int len, ret;
 
        if (query_item->flags)
                return -EINVAL;
 
+       for_each_uabi_engine(engine, i915)
+               num_uabi_engines++;
+
        len = sizeof(struct drm_i915_query_engine_info) +
-             RUNTIME_INFO(i915)->num_engines *
-             sizeof(struct drm_i915_engine_info);
+             num_uabi_engines * sizeof(struct drm_i915_engine_info);
 
        ret = copy_query_item(&query, sizeof(query), len, query_item);
        if (ret != 0)
index 868cc78..59aa1b6 100644 (file)
@@ -54,7 +54,8 @@ int __intel_wakeref_get_first(struct intel_wakeref *wf)
 
 static void ____intel_wakeref_put_last(struct intel_wakeref *wf)
 {
-       if (!atomic_dec_and_test(&wf->count))
+       INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
+       if (unlikely(!atomic_dec_and_test(&wf->count)))
                goto unlock;
 
        /* ops->put() must reschedule its own release on error/deferral */
@@ -67,13 +68,12 @@ unlock:
        mutex_unlock(&wf->mutex);
 }
 
-void __intel_wakeref_put_last(struct intel_wakeref *wf)
+void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags)
 {
        INTEL_WAKEREF_BUG_ON(work_pending(&wf->work));
 
        /* Assume we are not in process context and so cannot sleep. */
-       if (wf->ops->flags & INTEL_WAKEREF_PUT_ASYNC ||
-           !mutex_trylock(&wf->mutex)) {
+       if (flags & INTEL_WAKEREF_PUT_ASYNC || !mutex_trylock(&wf->mutex)) {
                schedule_work(&wf->work);
                return;
        }
@@ -109,8 +109,17 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 
 int intel_wakeref_wait_for_idle(struct intel_wakeref *wf)
 {
-       return wait_var_event_killable(&wf->wakeref,
-                                      !intel_wakeref_is_active(wf));
+       int err;
+
+       might_sleep();
+
+       err = wait_var_event_killable(&wf->wakeref,
+                                     !intel_wakeref_is_active(wf));
+       if (err)
+               return err;
+
+       intel_wakeref_unlock_wait(wf);
+       return 0;
 }
 
 static void wakeref_auto_timeout(struct timer_list *t)
index 5f0c972..da6e8fd 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/atomic.h>
 #include <linux/bits.h>
+#include <linux/lockdep.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
 #include <linux/stackdepot.h>
@@ -29,9 +30,6 @@ typedef depot_stack_handle_t intel_wakeref_t;
 struct intel_wakeref_ops {
        int (*get)(struct intel_wakeref *wf);
        int (*put)(struct intel_wakeref *wf);
-
-       unsigned long flags;
-#define INTEL_WAKEREF_PUT_ASYNC BIT(0)
 };
 
 struct intel_wakeref {
@@ -57,7 +55,7 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 } while (0)
 
 int __intel_wakeref_get_first(struct intel_wakeref *wf);
-void __intel_wakeref_put_last(struct intel_wakeref *wf);
+void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags);
 
 /**
  * intel_wakeref_get: Acquire the wakeref
@@ -100,10 +98,9 @@ intel_wakeref_get_if_active(struct intel_wakeref *wf)
 }
 
 /**
- * intel_wakeref_put: Release the wakeref
- * @i915: the drm_i915_private device
+ * intel_wakeref_put_flags: Release the wakeref
  * @wf: the wakeref
- * @fn: callback for releasing the wakeref, called only on final release.
+ * @flags: control flags
  *
  * Release our hold on the wakeref. When there are no more users,
  * the runtime pm wakeref will be released after the @fn callback is called
@@ -116,11 +113,25 @@ intel_wakeref_get_if_active(struct intel_wakeref *wf)
  * code otherwise.
  */
 static inline void
-intel_wakeref_put(struct intel_wakeref *wf)
+__intel_wakeref_put(struct intel_wakeref *wf, unsigned long flags)
+#define INTEL_WAKEREF_PUT_ASYNC BIT(0)
 {
        INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
        if (unlikely(!atomic_add_unless(&wf->count, -1, 1)))
-               __intel_wakeref_put_last(wf);
+               __intel_wakeref_put_last(wf, flags);
+}
+
+static inline void
+intel_wakeref_put(struct intel_wakeref *wf)
+{
+       might_sleep();
+       __intel_wakeref_put(wf, 0);
+}
+
+static inline void
+intel_wakeref_put_async(struct intel_wakeref *wf)
+{
+       __intel_wakeref_put(wf, INTEL_WAKEREF_PUT_ASYNC);
 }
 
 /**
@@ -152,6 +163,21 @@ intel_wakeref_unlock(struct intel_wakeref *wf)
 }
 
 /**
+ * intel_wakeref_unlock_wait: Wait until the active callback is complete
+ * @wf: the wakeref
+ *
+ * Waits for the active callback (under the @wf->mutex or another CPU) is
+ * complete.
+ */
+static inline void
+intel_wakeref_unlock_wait(struct intel_wakeref *wf)
+{
+       mutex_lock(&wf->mutex);
+       mutex_unlock(&wf->mutex);
+       flush_work(&wf->work);
+}
+
+/**
  * intel_wakeref_is_active: Query whether the wakeref is currently held
  * @wf: the wakeref
  *
@@ -170,6 +196,7 @@ intel_wakeref_is_active(const struct intel_wakeref *wf)
 static inline void
 __intel_wakeref_defer_park(struct intel_wakeref *wf)
 {
+       lockdep_assert_held(&wf->mutex);
        INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count));
        atomic_set_release(&wf->count, 1);
 }
index d6214d3..ef4c630 100644 (file)
@@ -935,11 +935,13 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
        for_each_available_child_of_node(dev->of_node, child) {
                panel = of_drm_find_panel(child);
                if (IS_ERR(panel)) {
-                       dev_err(dev, "failed to find panel try bridge (%lu)\n",
+                       dev_err(dev, "failed to find panel try bridge (%ld)\n",
                                PTR_ERR(panel));
+                       panel = NULL;
+
                        bridge = of_drm_find_bridge(child);
                        if (IS_ERR(bridge)) {
-                               dev_err(dev, "failed to find bridge (%lu)\n",
+                               dev_err(dev, "failed to find bridge (%ld)\n",
                                        PTR_ERR(bridge));
                                return PTR_ERR(bridge);
                        }
index 9ab27ae..1bd6b6d 100644 (file)
@@ -64,6 +64,25 @@ struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
        },
 };
 
+static const struct meson_cvbs_mode *
+meson_cvbs_get_mode(const struct drm_display_mode *req_mode)
+{
+       int i;
+
+       for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
+               struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
+
+               if (drm_mode_match(req_mode, &meson_mode->mode,
+                                  DRM_MODE_MATCH_TIMINGS |
+                                  DRM_MODE_MATCH_CLOCK |
+                                  DRM_MODE_MATCH_FLAGS |
+                                  DRM_MODE_MATCH_3D_FLAGS))
+                       return meson_mode;
+       }
+
+       return NULL;
+}
+
 /* Connector */
 
 static void meson_cvbs_connector_destroy(struct drm_connector *connector)
@@ -136,14 +155,8 @@ static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder,
                                        struct drm_crtc_state *crtc_state,
                                        struct drm_connector_state *conn_state)
 {
-       int i;
-
-       for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
-               struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
-
-               if (drm_mode_equal(&crtc_state->mode, &meson_mode->mode))
-                       return 0;
-       }
+       if (meson_cvbs_get_mode(&crtc_state->mode))
+               return 0;
 
        return -EINVAL;
 }
@@ -191,24 +204,17 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder,
                                   struct drm_display_mode *mode,
                                   struct drm_display_mode *adjusted_mode)
 {
+       const struct meson_cvbs_mode *meson_mode = meson_cvbs_get_mode(mode);
        struct meson_venc_cvbs *meson_venc_cvbs =
                                        encoder_to_meson_venc_cvbs(encoder);
        struct meson_drm *priv = meson_venc_cvbs->priv;
-       int i;
 
-       for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
-               struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
+       if (meson_mode) {
+               meson_venci_cvbs_mode_set(priv, meson_mode->enci);
 
-               if (drm_mode_equal(mode, &meson_mode->mode)) {
-                       meson_venci_cvbs_mode_set(priv,
-                                                 meson_mode->enci);
-
-                       /* Setup 27MHz vclk2 for ENCI and VDAC */
-                       meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
-                                        MESON_VCLK_CVBS, MESON_VCLK_CVBS,
-                                        MESON_VCLK_CVBS, true);
-                       break;
-               }
+               /* Setup 27MHz vclk2 for ENCI and VDAC */
+               meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS,
+                                MESON_VCLK_CVBS, MESON_VCLK_CVBS, true);
        }
 }
 
index 397f8b0..b113876 100644 (file)
@@ -30,7 +30,8 @@ module_param_named(modeset, mgag200_modeset, int, 0400);
 static struct drm_driver driver;
 
 static const struct pci_device_id pciidlist[] = {
-       { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A },
+       { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
        { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
        { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
        { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
@@ -60,6 +61,35 @@ static void mga_pci_remove(struct pci_dev *pdev)
 
 DEFINE_DRM_GEM_FOPS(mgag200_driver_fops);
 
+static bool mgag200_pin_bo_at_0(const struct mga_device *mdev)
+{
+       return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD;
+}
+
+int mgag200_driver_dumb_create(struct drm_file *file,
+                              struct drm_device *dev,
+                              struct drm_mode_create_dumb *args)
+{
+       struct mga_device *mdev = dev->dev_private;
+       unsigned long pg_align;
+
+       if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
+               return -EINVAL;
+
+       pg_align = 0ul;
+
+       /*
+        * Aligning scanout buffers to the size of the video ram forces
+        * placement at offset 0. Works around a bug where HW does not
+        * respect 'startadd' field.
+        */
+       if (mgag200_pin_bo_at_0(mdev))
+               pg_align = PFN_UP(mdev->mc.vram_size);
+
+       return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev,
+                                            pg_align, false, args);
+}
+
 static struct drm_driver driver = {
        .driver_features = DRIVER_GEM | DRIVER_MODESET,
        .load = mgag200_driver_load,
@@ -71,7 +101,10 @@ static struct drm_driver driver = {
        .major = DRIVER_MAJOR,
        .minor = DRIVER_MINOR,
        .patchlevel = DRIVER_PATCHLEVEL,
-       DRM_GEM_VRAM_DRIVER
+       .debugfs_init = drm_vram_mm_debugfs_init,
+       .dumb_create = mgag200_driver_dumb_create,
+       .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset,
+       .gem_prime_mmap = drm_gem_prime_mmap,
 };
 
 static struct pci_driver mgag200_pci_driver = {
index 0ea9a52..aa32aad 100644 (file)
@@ -150,6 +150,12 @@ enum mga_type {
        G200_EW3,
 };
 
+/* HW does not handle 'startadd' field correct. */
+#define MGAG200_FLAG_HW_BUG_NO_STARTADD        (1ul << 8)
+
+#define MGAG200_TYPE_MASK      (0x000000ff)
+#define MGAG200_FLAG_MASK      (0x00ffff00)
+
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
 struct mga_device {
@@ -181,6 +187,18 @@ struct mga_device {
        u32 unique_rev_id;
 };
 
+static inline enum mga_type
+mgag200_type_from_driver_data(kernel_ulong_t driver_data)
+{
+       return (enum mga_type)(driver_data & MGAG200_TYPE_MASK);
+}
+
+static inline unsigned long
+mgag200_flags_from_driver_data(kernel_ulong_t driver_data)
+{
+       return driver_data & MGAG200_FLAG_MASK;
+}
+
                                /* mgag200_mode.c */
 int mgag200_modeset_init(struct mga_device *mdev);
 void mgag200_modeset_fini(struct mga_device *mdev);
index 5f74aab..e1bc5b0 100644 (file)
@@ -94,7 +94,8 @@ static int mgag200_device_init(struct drm_device *dev,
        struct mga_device *mdev = dev->dev_private;
        int ret, option;
 
-       mdev->type = flags;
+       mdev->flags = mgag200_flags_from_driver_data(flags);
+       mdev->type = mgag200_type_from_driver_data(flags);
 
        /* Hardcode the number of CRTCs to 1 */
        mdev->num_crtc = 1;
index e9160ce..6deaa7d 100644 (file)
@@ -7,6 +7,7 @@ config DRM_MSM
        depends on OF && COMMON_CLK
        depends on MMU
        depends on INTERCONNECT || !INTERCONNECT
+       depends on QCOM_OCMEM || QCOM_OCMEM=n
        select QCOM_MDT_LOADER if ARCH_QCOM
        select REGULATOR
        select DRM_KMS_HELPER
index 5f7e980..7ad1493 100644 (file)
@@ -6,10 +6,6 @@
  * Copyright (c) 2014 The Linux Foundation. All rights reserved.
  */
 
-#ifdef CONFIG_MSM_OCMEM
-#  include <mach/ocmem.h>
-#endif
-
 #include "a3xx_gpu.h"
 
 #define A3XX_INT0_MASK \
@@ -195,9 +191,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
                gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x00000000);
 
        /* Set the OCMEM base address for A330, etc */
-       if (a3xx_gpu->ocmem_hdl) {
+       if (a3xx_gpu->ocmem.hdl) {
                gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR,
-                       (unsigned int)(a3xx_gpu->ocmem_base >> 14));
+                       (unsigned int)(a3xx_gpu->ocmem.base >> 14));
        }
 
        /* Turn on performance counters: */
@@ -318,10 +314,7 @@ static void a3xx_destroy(struct msm_gpu *gpu)
 
        adreno_gpu_cleanup(adreno_gpu);
 
-#ifdef CONFIG_MSM_OCMEM
-       if (a3xx_gpu->ocmem_base)
-               ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl);
-#endif
+       adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem);
 
        kfree(a3xx_gpu);
 }
@@ -494,17 +487,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
 
        /* if needed, allocate gmem: */
        if (adreno_is_a330(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-               /* TODO this is different/missing upstream: */
-               struct ocmem_buf *ocmem_hdl =
-                               ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
-
-               a3xx_gpu->ocmem_hdl = ocmem_hdl;
-               a3xx_gpu->ocmem_base = ocmem_hdl->addr;
-               adreno_gpu->gmem = ocmem_hdl->len;
-               DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
-                               a3xx_gpu->ocmem_base);
-#endif
+               ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev,
+                                           adreno_gpu, &a3xx_gpu->ocmem);
+               if (ret)
+                       goto fail;
        }
 
        if (!gpu->aspace) {
index 5dc33e5..c555fb1 100644 (file)
@@ -19,8 +19,7 @@ struct a3xx_gpu {
        struct adreno_gpu base;
 
        /* if OCMEM is used for GMEM: */
-       uint32_t ocmem_base;
-       void *ocmem_hdl;
+       struct adreno_ocmem ocmem;
 };
 #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base)
 
index ab2b752..b01388a 100644 (file)
@@ -2,9 +2,6 @@
 /* Copyright (c) 2014 The Linux Foundation. All rights reserved.
  */
 #include "a4xx_gpu.h"
-#ifdef CONFIG_MSM_OCMEM
-#  include <soc/qcom/ocmem.h>
-#endif
 
 #define A4XX_INT0_MASK \
        (A4XX_INT0_RBBM_AHB_ERROR |        \
@@ -188,7 +185,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
                        (1 << 30) | 0xFFFF);
 
        gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR,
-                       (unsigned int)(a4xx_gpu->ocmem_base >> 14));
+                       (unsigned int)(a4xx_gpu->ocmem.base >> 14));
 
        /* Turn on performance counters: */
        gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01);
@@ -318,10 +315,7 @@ static void a4xx_destroy(struct msm_gpu *gpu)
 
        adreno_gpu_cleanup(adreno_gpu);
 
-#ifdef CONFIG_MSM_OCMEM
-       if (a4xx_gpu->ocmem_base)
-               ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl);
-#endif
+       adreno_gpu_ocmem_cleanup(&a4xx_gpu->ocmem);
 
        kfree(a4xx_gpu);
 }
@@ -578,17 +572,10 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
 
        /* if needed, allocate gmem: */
        if (adreno_is_a4xx(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-               /* TODO this is different/missing upstream: */
-               struct ocmem_buf *ocmem_hdl =
-                               ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
-
-               a4xx_gpu->ocmem_hdl = ocmem_hdl;
-               a4xx_gpu->ocmem_base = ocmem_hdl->addr;
-               adreno_gpu->gmem = ocmem_hdl->len;
-               DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
-                               a4xx_gpu->ocmem_base);
-#endif
+               ret = adreno_gpu_ocmem_init(dev->dev, adreno_gpu,
+                                           &a4xx_gpu->ocmem);
+               if (ret)
+                       goto fail;
        }
 
        if (!gpu->aspace) {
index d506311..a01448c 100644 (file)
@@ -16,8 +16,7 @@ struct a4xx_gpu {
        struct adreno_gpu base;
 
        /* if OCMEM is used for GMEM: */
-       uint32_t ocmem_base;
-       void *ocmem_hdl;
+       struct adreno_ocmem ocmem;
 };
 #define to_a4xx_gpu(x) container_of(x, struct a4xx_gpu, base)
 
index e9c55d1..b02e204 100644 (file)
@@ -353,6 +353,9 @@ static int a5xx_me_init(struct msm_gpu *gpu)
                 * 2D mode 3 draw
                 */
                OUT_RING(ring, 0x0000000B);
+       } else if (adreno_is_a510(adreno_gpu)) {
+               /* Workaround for token and syncs */
+               OUT_RING(ring, 0x00000001);
        } else {
                /* No workarounds enabled */
                OUT_RING(ring, 0x00000000);
@@ -568,15 +571,24 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
                0x00100000 + adreno_gpu->gmem - 1);
        gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000);
 
-       gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40);
-       if (adreno_is_a530(adreno_gpu))
-               gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40);
-       if (adreno_is_a540(adreno_gpu))
-               gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400);
-       gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
-       gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
-
-       gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22));
+       if (adreno_is_a510(adreno_gpu)) {
+               gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x20);
+               gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x20);
+               gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x40000030);
+               gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A);
+               gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
+                         (0x200 << 11 | 0x200 << 22));
+       } else {
+               gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40);
+               if (adreno_is_a530(adreno_gpu))
+                       gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40);
+               if (adreno_is_a540(adreno_gpu))
+                       gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400);
+               gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
+               gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
+               gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
+                         (0x400 << 11 | 0x300 << 22));
+       }
 
        if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI)
                gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8));
@@ -589,6 +601,19 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
        /* Enable ME/PFP split notification */
        gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
 
+       /*
+        *  In A5x, CCU can send context_done event of a particular context to
+        *  UCHE which ultimately reaches CP even when there is valid
+        *  transaction of that context inside CCU. This can let CP to program
+        *  config registers, which will make the "valid transaction" inside
+        *  CCU to be interpreted differently. This can cause gpu fault. This
+        *  bug is fixed in latest A510 revision. To enable this bug fix -
+        *  bit[11] of RB_DBG_ECO_CNTL need to be set to 0, default is 1
+        *  (disable). For older A510 version this bit is unused.
+        */
+       if (adreno_is_a510(adreno_gpu))
+               gpu_rmw(gpu, REG_A5XX_RB_DBG_ECO_CNTL, (1 << 11), 0);
+
        /* Enable HWCG */
        a5xx_set_hwcg(gpu, true);
 
@@ -635,7 +660,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
        /* UCHE */
        gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16));
 
-       if (adreno_is_a530(adreno_gpu))
+       if (adreno_is_a530(adreno_gpu) || adreno_is_a510(adreno_gpu))
                gpu_write(gpu, REG_A5XX_CP_PROTECT(17),
                        ADRENO_PROTECT_RW(0x10000, 0x8000));
 
@@ -679,7 +704,8 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 
        a5xx_preempt_hw_init(gpu);
 
-       a5xx_gpmu_ucode_init(gpu);
+       if (!adreno_is_a510(adreno_gpu))
+               a5xx_gpmu_ucode_init(gpu);
 
        ret = a5xx_ucode_init(gpu);
        if (ret)
@@ -712,7 +738,8 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
        }
 
        /*
-        * Try to load a zap shader into the secure world. If successful
+        * If the chip that we are using does support loading one, then
+        * try to load a zap shader into the secure world. If successful
         * we can use the CP to switch out of secure mode. If not then we
         * have no resource but to try to switch ourselves out manually. If we
         * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
@@ -1066,6 +1093,7 @@ static void a5xx_dump(struct msm_gpu *gpu)
 
 static int a5xx_pm_resume(struct msm_gpu *gpu)
 {
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        int ret;
 
        /* Turn on the core power */
@@ -1073,6 +1101,15 @@ static int a5xx_pm_resume(struct msm_gpu *gpu)
        if (ret)
                return ret;
 
+       if (adreno_is_a510(adreno_gpu)) {
+               /* Halt the sp_input_clk at HM level */
+               gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0x00000055);
+               a5xx_set_hwcg(gpu, true);
+               /* Turn on sp_input_clk at HM level */
+               gpu_rmw(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xff, 0);
+               return 0;
+       }
+
        /* Turn the RBCCU domain first to limit the chances of voltage droop */
        gpu_write(gpu, REG_A5XX_GPMU_RBCCU_POWER_CNTL, 0x778000);
 
@@ -1101,9 +1138,17 @@ static int a5xx_pm_resume(struct msm_gpu *gpu)
 
 static int a5xx_pm_suspend(struct msm_gpu *gpu)
 {
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       u32 mask = 0xf;
+
+       /* A510 has 3 XIN ports in VBIF */
+       if (adreno_is_a510(adreno_gpu))
+               mask = 0x7;
+
        /* Clear the VBIF pipe before shutting down */
-       gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0xF);
-       spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) & 0xF) == 0xF);
+       gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, mask);
+       spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) &
+                               mask) == mask);
 
        gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0);
 
@@ -1289,7 +1334,7 @@ static void a5xx_gpu_state_destroy(struct kref *kref)
        kfree(a5xx_state);
 }
 
-int a5xx_gpu_state_put(struct msm_gpu_state *state)
+static int a5xx_gpu_state_put(struct msm_gpu_state *state)
 {
        if (IS_ERR_OR_NULL(state))
                return 1;
@@ -1299,8 +1344,8 @@ int a5xx_gpu_state_put(struct msm_gpu_state *state)
 
 
 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
-void a5xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
-               struct drm_printer *p)
+static void a5xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+                     struct drm_printer *p)
 {
        int i, j;
        u32 pos = 0;
index a3a06db..321a806 100644 (file)
@@ -297,6 +297,10 @@ int a5xx_power_init(struct msm_gpu *gpu)
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        int ret;
 
+       /* Not all A5xx chips have a GPMU */
+       if (adreno_is_a510(adreno_gpu))
+               return 0;
+
        /* Set up the limits management */
        if (adreno_is_a530(adreno_gpu))
                a530_lm_setup(gpu);
@@ -326,6 +330,9 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
        unsigned int *data, *ptr, *cmds;
        unsigned int cmds_size;
 
+       if (adreno_is_a510(adreno_gpu))
+               return;
+
        if (a5xx_gpu->gpmu_bo)
                return;
 
index 0888e0d..fbbdf86 100644 (file)
@@ -115,6 +115,21 @@ static const struct adreno_info gpulist[] = {
                .inactive_period = DRM_MSM_INACTIVE_PERIOD,
                .init  = a4xx_gpu_init,
        }, {
+               .rev   = ADRENO_REV(5, 1, 0, ANY_ID),
+               .revn = 510,
+               .name = "A510",
+               .fw = {
+                       [ADRENO_FW_PM4] = "a530_pm4.fw",
+                       [ADRENO_FW_PFP] = "a530_pfp.fw",
+               },
+               .gmem = SZ_256K,
+               /*
+                * Increase inactive period to 250 to avoid bouncing
+                * the GDSC which appears to make it grumpy
+                */
+               .inactive_period = 250,
+               .init = a5xx_gpu_init,
+       }, {
                .rev = ADRENO_REV(5, 3, 0, 2),
                .revn = 530,
                .name = "A530",
index 048c8be..0783e4b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pm_opp.h>
 #include <linux/slab.h>
 #include <linux/soc/qcom/mdt_loader.h>
+#include <soc/qcom/ocmem.h>
 #include "adreno_gpu.h"
 #include "msm_gem.h"
 #include "msm_mmu.h"
@@ -893,6 +894,45 @@ static int adreno_get_pwrlevels(struct device *dev,
        return 0;
 }
 
+int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu,
+                         struct adreno_ocmem *adreno_ocmem)
+{
+       struct ocmem_buf *ocmem_hdl;
+       struct ocmem *ocmem;
+
+       ocmem = of_get_ocmem(dev);
+       if (IS_ERR(ocmem)) {
+               if (PTR_ERR(ocmem) == -ENODEV) {
+                       /*
+                        * Return success since either the ocmem property was
+                        * not specified in device tree, or ocmem support is
+                        * not compiled into the kernel.
+                        */
+                       return 0;
+               }
+
+               return PTR_ERR(ocmem);
+       }
+
+       ocmem_hdl = ocmem_allocate(ocmem, OCMEM_GRAPHICS, adreno_gpu->gmem);
+       if (IS_ERR(ocmem_hdl))
+               return PTR_ERR(ocmem_hdl);
+
+       adreno_ocmem->ocmem = ocmem;
+       adreno_ocmem->base = ocmem_hdl->addr;
+       adreno_ocmem->hdl = ocmem_hdl;
+       adreno_gpu->gmem = ocmem_hdl->len;
+
+       return 0;
+}
+
+void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem)
+{
+       if (adreno_ocmem && adreno_ocmem->base)
+               ocmem_free(adreno_ocmem->ocmem, OCMEM_GRAPHICS,
+                          adreno_ocmem->hdl);
+}
+
 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
                struct adreno_gpu *adreno_gpu,
                const struct adreno_gpu_funcs *funcs, int nr_rings)
index c7441fb..e71a757 100644 (file)
@@ -126,6 +126,12 @@ struct adreno_gpu {
 };
 #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
 
+struct adreno_ocmem {
+       struct ocmem *ocmem;
+       unsigned long base;
+       void *hdl;
+};
+
 /* platform config data (ie. from DT, or pdata) */
 struct adreno_platform_config {
        struct adreno_rev rev;
@@ -206,6 +212,11 @@ static inline int adreno_is_a430(struct adreno_gpu *gpu)
        return gpu->revn == 430;
 }
 
+static inline int adreno_is_a510(struct adreno_gpu *gpu)
+{
+       return gpu->revn == 510;
+}
+
 static inline int adreno_is_a530(struct adreno_gpu *gpu)
 {
        return gpu->revn == 530;
@@ -236,6 +247,10 @@ void adreno_dump(struct msm_gpu *gpu);
 void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords);
 struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu);
 
+int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu,
+                         struct adreno_ocmem *ocmem);
+void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *ocmem);
+
 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
                struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
                int nr_rings);
index cdbea38..f1bc6a1 100644 (file)
@@ -55,8 +55,7 @@ static void dpu_core_irq_callback_handler(void *arg, int irq_idx)
 int dpu_core_irq_idx_lookup(struct dpu_kms *dpu_kms,
                enum dpu_intr_type intr_type, u32 instance_idx)
 {
-       if (!dpu_kms || !dpu_kms->hw_intr ||
-                       !dpu_kms->hw_intr->ops.irq_idx_lookup)
+       if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.irq_idx_lookup)
                return -EINVAL;
 
        return dpu_kms->hw_intr->ops.irq_idx_lookup(intr_type,
@@ -73,7 +72,7 @@ static int _dpu_core_irq_enable(struct dpu_kms *dpu_kms, int irq_idx)
        unsigned long irq_flags;
        int ret = 0, enable_count;
 
-       if (!dpu_kms || !dpu_kms->hw_intr ||
+       if (!dpu_kms->hw_intr ||
                        !dpu_kms->irq_obj.enable_counts ||
                        !dpu_kms->irq_obj.irq_counts) {
                DPU_ERROR("invalid params\n");
@@ -114,7 +113,7 @@ int dpu_core_irq_enable(struct dpu_kms *dpu_kms, int *irq_idxs, u32 irq_count)
 {
        int i, ret = 0, counts;
 
-       if (!dpu_kms || !irq_idxs || !irq_count) {
+       if (!irq_idxs || !irq_count) {
                DPU_ERROR("invalid params\n");
                return -EINVAL;
        }
@@ -138,7 +137,7 @@ static int _dpu_core_irq_disable(struct dpu_kms *dpu_kms, int irq_idx)
 {
        int ret = 0, enable_count;
 
-       if (!dpu_kms || !dpu_kms->hw_intr || !dpu_kms->irq_obj.enable_counts) {
+       if (!dpu_kms->hw_intr || !dpu_kms->irq_obj.enable_counts) {
                DPU_ERROR("invalid params\n");
                return -EINVAL;
        }
@@ -169,7 +168,7 @@ int dpu_core_irq_disable(struct dpu_kms *dpu_kms, int *irq_idxs, u32 irq_count)
 {
        int i, ret = 0, counts;
 
-       if (!dpu_kms || !irq_idxs || !irq_count) {
+       if (!irq_idxs || !irq_count) {
                DPU_ERROR("invalid params\n");
                return -EINVAL;
        }
@@ -186,7 +185,7 @@ int dpu_core_irq_disable(struct dpu_kms *dpu_kms, int *irq_idxs, u32 irq_count)
 
 u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx, bool clear)
 {
-       if (!dpu_kms || !dpu_kms->hw_intr ||
+       if (!dpu_kms->hw_intr ||
                        !dpu_kms->hw_intr->ops.get_interrupt_status)
                return 0;
 
@@ -205,7 +204,7 @@ int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, int irq_idx,
 {
        unsigned long irq_flags;
 
-       if (!dpu_kms || !dpu_kms->irq_obj.irq_cb_tbl) {
+       if (!dpu_kms->irq_obj.irq_cb_tbl) {
                DPU_ERROR("invalid params\n");
                return -EINVAL;
        }
@@ -240,7 +239,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx,
 {
        unsigned long irq_flags;
 
-       if (!dpu_kms || !dpu_kms->irq_obj.irq_cb_tbl) {
+       if (!dpu_kms->irq_obj.irq_cb_tbl) {
                DPU_ERROR("invalid params\n");
                return -EINVAL;
        }
@@ -274,8 +273,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx,
 
 static void dpu_clear_all_irqs(struct dpu_kms *dpu_kms)
 {
-       if (!dpu_kms || !dpu_kms->hw_intr ||
-                       !dpu_kms->hw_intr->ops.clear_all_irqs)
+       if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.clear_all_irqs)
                return;
 
        dpu_kms->hw_intr->ops.clear_all_irqs(dpu_kms->hw_intr);
@@ -283,8 +281,7 @@ static void dpu_clear_all_irqs(struct dpu_kms *dpu_kms)
 
 static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms)
 {
-       if (!dpu_kms || !dpu_kms->hw_intr ||
-                       !dpu_kms->hw_intr->ops.disable_all_irqs)
+       if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.disable_all_irqs)
                return;
 
        dpu_kms->hw_intr->ops.disable_all_irqs(dpu_kms->hw_intr);
@@ -343,18 +340,8 @@ void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms,
 
 void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
 {
-       struct msm_drm_private *priv;
        int i;
 
-       if (!dpu_kms->dev) {
-               DPU_ERROR("invalid drm device\n");
-               return;
-       } else if (!dpu_kms->dev->dev_private) {
-               DPU_ERROR("invalid device private\n");
-               return;
-       }
-       priv = dpu_kms->dev->dev_private;
-
        pm_runtime_get_sync(&dpu_kms->pdev->dev);
        dpu_clear_all_irqs(dpu_kms);
        dpu_disable_all_irqs(dpu_kms);
@@ -379,18 +366,8 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
 
 void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
 {
-       struct msm_drm_private *priv;
        int i;
 
-       if (!dpu_kms->dev) {
-               DPU_ERROR("invalid drm device\n");
-               return;
-       } else if (!dpu_kms->dev->dev_private) {
-               DPU_ERROR("invalid device private\n");
-               return;
-       }
-       priv = dpu_kms->dev->dev_private;
-
        pm_runtime_get_sync(&dpu_kms->pdev->dev);
        for (i = 0; i < dpu_kms->irq_obj.total_irqs; i++)
                if (atomic_read(&dpu_kms->irq_obj.enable_counts[i]) ||
index 09a49b5..11f2beb 100644 (file)
@@ -32,18 +32,7 @@ enum dpu_perf_mode {
 static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
 {
        struct msm_drm_private *priv;
-
-       if (!crtc->dev || !crtc->dev->dev_private) {
-               DPU_ERROR("invalid device\n");
-               return NULL;
-       }
-
        priv = crtc->dev->dev_private;
-       if (!priv || !priv->kms) {
-               DPU_ERROR("invalid kms\n");
-               return NULL;
-       }
-
        return to_dpu_kms(priv->kms);
 }
 
@@ -116,7 +105,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
        }
 
        kms = _dpu_crtc_get_kms(crtc);
-       if (!kms || !kms->catalog) {
+       if (!kms->catalog) {
                DPU_ERROR("invalid parameters\n");
                return 0;
        }
@@ -215,7 +204,6 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
 void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
 {
        struct dpu_crtc *dpu_crtc;
-       struct dpu_crtc_state *dpu_cstate;
        struct dpu_kms *kms;
 
        if (!crtc) {
@@ -224,13 +212,12 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
        }
 
        kms = _dpu_crtc_get_kms(crtc);
-       if (!kms || !kms->catalog) {
+       if (!kms->catalog) {
                DPU_ERROR("invalid kms\n");
                return;
        }
 
        dpu_crtc = to_dpu_crtc(crtc);
-       dpu_cstate = to_dpu_crtc_state(crtc->state);
 
        if (atomic_dec_return(&kms->bandwidth_ref) > 0)
                return;
@@ -287,7 +274,6 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
        u64 clk_rate = 0;
        struct dpu_crtc *dpu_crtc;
        struct dpu_crtc_state *dpu_cstate;
-       struct msm_drm_private *priv;
        struct dpu_kms *kms;
        int ret;
 
@@ -297,11 +283,10 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
        }
 
        kms = _dpu_crtc_get_kms(crtc);
-       if (!kms || !kms->catalog) {
+       if (!kms->catalog) {
                DPU_ERROR("invalid kms\n");
                return -EINVAL;
        }
-       priv = kms->dev->dev_private;
 
        dpu_crtc = to_dpu_crtc(crtc);
        dpu_cstate = to_dpu_crtc_state(crtc->state);
index ce59adf..f197dce 100644 (file)
@@ -266,11 +266,20 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc)
 {
        struct drm_encoder *encoder;
 
-       if (!crtc || !crtc->dev) {
+       if (!crtc) {
                DPU_ERROR("invalid crtc\n");
                return INTF_MODE_NONE;
        }
 
+       /*
+        * TODO: This function is called from dpu debugfs and as part of atomic
+        * check. When called from debugfs, the crtc->mutex must be held to
+        * read crtc->state. However reading crtc->state from atomic check isn't
+        * allowed (unless you have a good reason, a big comment, and a deep
+        * understanding of how the atomic/modeset locks work (<- and this is
+        * probably not possible)). So we'll keep the WARN_ON here for now, but
+        * really we need to figure out a better way to track our operating mode
+        */
        WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
 
        /* TODO: Returns the first INTF_MODE, could there be multiple values? */
@@ -694,7 +703,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
        unsigned long flags;
        bool release_bandwidth = false;
 
-       if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) {
+       if (!crtc || !crtc->state) {
                DPU_ERROR("invalid crtc\n");
                return;
        }
@@ -766,7 +775,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
        struct msm_drm_private *priv;
        bool request_bandwidth;
 
-       if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
+       if (!crtc) {
                DPU_ERROR("invalid crtc\n");
                return;
        }
@@ -1288,13 +1297,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
 {
        struct drm_crtc *crtc = NULL;
        struct dpu_crtc *dpu_crtc = NULL;
-       struct msm_drm_private *priv = NULL;
-       struct dpu_kms *kms = NULL;
        int i;
 
-       priv = dev->dev_private;
-       kms = to_dpu_kms(priv->kms);
-
        dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL);
        if (!dpu_crtc)
                return ERR_PTR(-ENOMEM);
index d82ea99..f96e142 100644 (file)
@@ -645,11 +645,6 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
        priv = drm_enc->dev->dev_private;
 
        dpu_kms = to_dpu_kms(priv->kms);
-       if (!dpu_kms) {
-               DPU_ERROR("invalid dpu_kms\n");
-               return;
-       }
-
        hw_mdptop = dpu_kms->hw_mdp;
        if (!hw_mdptop) {
                DPU_ERROR("invalid mdptop\n");
@@ -735,8 +730,7 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc,
        struct msm_drm_private *priv;
        bool is_vid_mode = false;
 
-       if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
-                       !drm_enc->crtc) {
+       if (!drm_enc || !drm_enc->dev || !drm_enc->crtc) {
                DPU_ERROR("invalid parameters\n");
                return -EINVAL;
        }
@@ -1092,17 +1086,13 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
        struct msm_drm_private *priv;
        struct dpu_kms *dpu_kms;
 
-       if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
+       if (!drm_enc || !drm_enc->dev) {
                DPU_ERROR("invalid parameters\n");
                return;
        }
 
        priv = drm_enc->dev->dev_private;
        dpu_kms = to_dpu_kms(priv->kms);
-       if (!dpu_kms) {
-               DPU_ERROR("invalid dpu_kms\n");
-               return;
-       }
 
        dpu_enc = to_dpu_encoder_virt(drm_enc);
        if (!dpu_enc || !dpu_enc->cur_master) {
@@ -1184,7 +1174,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
        struct dpu_encoder_virt *dpu_enc = NULL;
        struct msm_drm_private *priv;
        struct dpu_kms *dpu_kms;
-       struct drm_display_mode *mode;
        int i = 0;
 
        if (!drm_enc) {
@@ -1193,9 +1182,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
        } else if (!drm_enc->dev) {
                DPU_ERROR("invalid dev\n");
                return;
-       } else if (!drm_enc->dev->dev_private) {
-               DPU_ERROR("invalid dev_private\n");
-               return;
        }
 
        dpu_enc = to_dpu_encoder_virt(drm_enc);
@@ -1204,8 +1190,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
        mutex_lock(&dpu_enc->enc_lock);
        dpu_enc->enabled = false;
 
-       mode = &drm_enc->crtc->state->adjusted_mode;
-
        priv = drm_enc->dev->dev_private;
        dpu_kms = to_dpu_kms(priv->kms);
 
@@ -1734,8 +1718,7 @@ static void dpu_encoder_vsync_event_handler(struct timer_list *t)
        struct msm_drm_private *priv;
        struct msm_drm_thread *event_thread;
 
-       if (!drm_enc->dev || !drm_enc->dev->dev_private ||
-                       !drm_enc->crtc) {
+       if (!drm_enc->dev || !drm_enc->crtc) {
                DPU_ERROR("invalid parameters\n");
                return;
        }
@@ -1914,8 +1897,6 @@ static int _dpu_encoder_debugfs_status_open(struct inode *inode,
 static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
 {
        struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
-       struct msm_drm_private *priv;
-       struct dpu_kms *dpu_kms;
        int i;
 
        static const struct file_operations debugfs_status_fops = {
@@ -1927,14 +1908,11 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
 
        char name[DPU_NAME_SIZE];
 
-       if (!drm_enc->dev || !drm_enc->dev->dev_private) {
+       if (!drm_enc->dev) {
                DPU_ERROR("invalid encoder or kms\n");
                return -EINVAL;
        }
 
-       priv = drm_enc->dev->dev_private;
-       dpu_kms = to_dpu_kms(priv->kms);
-
        snprintf(name, DPU_NAME_SIZE, "encoder%u", drm_enc->base.id);
 
        /* create overall sub-directory for the encoder */
@@ -2042,9 +2020,8 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
        enum dpu_intf_type intf_type;
        struct dpu_enc_phys_init_params phys_params;
 
-       if (!dpu_enc || !dpu_kms) {
-               DPU_ERROR("invalid arg(s), enc %d kms %d\n",
-                               dpu_enc != 0, dpu_kms != 0);
+       if (!dpu_enc) {
+               DPU_ERROR("invalid arg(s), enc %d\n", dpu_enc != 0);
                return -EINVAL;
        }
 
@@ -2133,14 +2110,12 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
        struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t,
                        frame_done_timer);
        struct drm_encoder *drm_enc = &dpu_enc->base;
-       struct msm_drm_private *priv;
        u32 event;
 
-       if (!drm_enc->dev || !drm_enc->dev->dev_private) {
+       if (!drm_enc->dev) {
                DPU_ERROR("invalid parameters\n");
                return;
        }
-       priv = drm_enc->dev->dev_private;
 
        if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc_frame_event_cb) {
                DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n",
index 2923b63..0479609 100644 (file)
@@ -124,13 +124,11 @@ static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
 static void dpu_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx)
 {
        struct dpu_encoder_phys *phys_enc = arg;
-       struct dpu_encoder_phys_cmd *cmd_enc;
 
        if (!phys_enc || !phys_enc->hw_ctl)
                return;
 
        DPU_ATRACE_BEGIN("ctl_start_irq");
-       cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
 
        atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
 
@@ -316,13 +314,9 @@ end:
 static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
                bool enable)
 {
-       struct dpu_encoder_phys_cmd *cmd_enc;
-
        if (!phys_enc)
                return;
 
-       cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
-
        trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
                        phys_enc->hw_pp->idx - PINGPONG_0,
                        enable, atomic_read(&phys_enc->vblank_refcount));
@@ -355,7 +349,6 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
        struct drm_display_mode *mode;
        bool tc_enable = true;
        u32 vsync_hz;
-       struct msm_drm_private *priv;
        struct dpu_kms *dpu_kms;
 
        if (!phys_enc || !phys_enc->hw_pp) {
@@ -373,11 +366,6 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
        }
 
        dpu_kms = phys_enc->dpu_kms;
-       if (!dpu_kms || !dpu_kms->dev || !dpu_kms->dev->dev_private) {
-               DPU_ERROR("invalid device\n");
-               return;
-       }
-       priv = dpu_kms->dev->dev_private;
 
        /*
         * TE default: dsi byte clock calculated base on 70 fps;
@@ -650,13 +638,10 @@ static int dpu_encoder_phys_cmd_wait_for_tx_complete(
                struct dpu_encoder_phys *phys_enc)
 {
        int rc;
-       struct dpu_encoder_phys_cmd *cmd_enc;
 
        if (!phys_enc)
                return -EINVAL;
 
-       cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
-
        rc = _dpu_encoder_phys_cmd_wait_for_idle(phys_enc);
        if (rc) {
                DRM_ERROR("failed wait_for_idle: id:%u ret:%d intf:%d\n",
index b9c84fb..3123ef8 100644 (file)
@@ -374,7 +374,7 @@ static void dpu_encoder_phys_vid_mode_set(
                struct drm_display_mode *mode,
                struct drm_display_mode *adj_mode)
 {
-       if (!phys_enc || !phys_enc->dpu_kms) {
+       if (!phys_enc) {
                DPU_ERROR("invalid encoder/kms\n");
                return;
        }
@@ -566,16 +566,13 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
 
 static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
 {
-       struct msm_drm_private *priv;
        unsigned long lock_flags;
        int ret;
 
-       if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev ||
-                       !phys_enc->parent->dev->dev_private) {
+       if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev) {
                DPU_ERROR("invalid encoder/device\n");
                return;
        }
-       priv = phys_enc->parent->dev->dev_private;
 
        if (!phys_enc->hw_intf || !phys_enc->hw_ctl) {
                DPU_ERROR("invalid hw_intf %d hw_ctl %d\n",
index 58b0485..6c92f0f 100644 (file)
 #define CREATE_TRACE_POINTS
 #include "dpu_trace.h"
 
-static const char * const iommu_ports[] = {
-               "mdp_0",
-};
-
 /*
  * To enable overall DRM driver logging
  * # echo 0x2 > /sys/module/drm/parameters/debug
@@ -68,16 +64,14 @@ static int _dpu_danger_signal_status(struct seq_file *s,
                bool danger_status)
 {
        struct dpu_kms *kms = (struct dpu_kms *)s->private;
-       struct msm_drm_private *priv;
        struct dpu_danger_safe_status status;
        int i;
 
-       if (!kms->dev || !kms->dev->dev_private || !kms->hw_mdp) {
+       if (!kms->hw_mdp) {
                DPU_ERROR("invalid arg(s)\n");
                return 0;
        }
 
-       priv = kms->dev->dev_private;
        memset(&status, 0, sizeof(struct dpu_danger_safe_status));
 
        pm_runtime_get_sync(&kms->pdev->dev);
@@ -153,13 +147,7 @@ static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
                return 0;
 
        dev = dpu_kms->dev;
-       if (!dev)
-               return 0;
-
        priv = dev->dev_private;
-       if (!priv)
-               return 0;
-
        base = dpu_kms->mmio + regset->offset;
 
        /* insert padding spaces, if needed */
@@ -280,7 +268,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
                struct drm_atomic_state *state)
 {
        struct dpu_kms *dpu_kms;
-       struct msm_drm_private *priv;
        struct drm_device *dev;
        struct drm_crtc *crtc;
        struct drm_crtc_state *crtc_state;
@@ -292,10 +279,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
        dpu_kms = to_dpu_kms(kms);
        dev = dpu_kms->dev;
 
-       if (!dev || !dev->dev_private)
-               return;
-       priv = dev->dev_private;
-
        /* Call prepare_commit for all affected encoders */
        for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
                drm_for_each_encoder_mask(encoder, crtc->dev,
@@ -333,7 +316,6 @@ void dpu_kms_encoder_enable(struct drm_encoder *encoder)
        if (funcs && funcs->commit)
                funcs->commit(encoder);
 
-       WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
        drm_for_each_crtc(crtc, dev) {
                if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder)))
                        continue;
@@ -464,16 +446,6 @@ static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)
        struct msm_drm_private *priv;
        int i;
 
-       if (!dpu_kms) {
-               DPU_ERROR("invalid dpu_kms\n");
-               return;
-       } else if (!dpu_kms->dev) {
-               DPU_ERROR("invalid dev\n");
-               return;
-       } else if (!dpu_kms->dev->dev_private) {
-               DPU_ERROR("invalid dev_private\n");
-               return;
-       }
        priv = dpu_kms->dev->dev_private;
 
        for (i = 0; i < priv->num_crtcs; i++)
@@ -505,7 +477,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 
        int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret;
        int max_crtc_count;
-
        dev = dpu_kms->dev;
        priv = dev->dev_private;
        catalog = dpu_kms->catalog;
@@ -585,8 +556,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
        int i;
 
        dev = dpu_kms->dev;
-       if (!dev)
-               return;
 
        if (dpu_kms->hw_intr)
                dpu_hw_intr_destroy(dpu_kms->hw_intr);
@@ -725,8 +694,7 @@ static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms)
 
        mmu = dpu_kms->base.aspace->mmu;
 
-       mmu->funcs->detach(mmu, (const char **)iommu_ports,
-                       ARRAY_SIZE(iommu_ports));
+       mmu->funcs->detach(mmu);
        msm_gem_address_space_put(dpu_kms->base.aspace);
 
        dpu_kms->base.aspace = NULL;
@@ -752,8 +720,7 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
                return PTR_ERR(aspace);
        }
 
-       ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
-                       ARRAY_SIZE(iommu_ports));
+       ret = aspace->mmu->funcs->attach(aspace->mmu);
        if (ret) {
                DPU_ERROR("failed to attach iommu %d\n", ret);
                msm_gem_address_space_put(aspace);
@@ -803,16 +770,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 
        dpu_kms = to_dpu_kms(kms);
        dev = dpu_kms->dev;
-       if (!dev) {
-               DPU_ERROR("invalid device\n");
-               return rc;
-       }
-
        priv = dev->dev_private;
-       if (!priv) {
-               DPU_ERROR("invalid private data\n");
-               return rc;
-       }
 
        atomic_set(&dpu_kms->bandwidth_ref, 0);
 
@@ -974,7 +932,7 @@ struct msm_kms *dpu_kms_init(struct drm_device *dev)
        struct dpu_kms *dpu_kms;
        int irq;
 
-       if (!dev || !dev->dev_private) {
+       if (!dev) {
                DPU_ERROR("drm device node invalid\n");
                return ERR_PTR(-EINVAL);
        }
@@ -1064,11 +1022,6 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev)
        struct dss_module_power *mp = &dpu_kms->mp;
 
        ddev = dpu_kms->dev;
-       if (!ddev) {
-               DPU_ERROR("invalid drm_device\n");
-               return rc;
-       }
-
        rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
        if (rc)
                DPU_ERROR("clock disable failed rc:%d\n", rc);
@@ -1086,11 +1039,6 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev)
        struct dss_module_power *mp = &dpu_kms->mp;
 
        ddev = dpu_kms->dev;
-       if (!ddev) {
-               DPU_ERROR("invalid drm_device\n");
-               return rc;
-       }
-
        rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
        if (rc) {
                DPU_ERROR("clock enable failed rc:%d\n", rc);
index 959d03e..c6169e7 100644 (file)
@@ -139,10 +139,6 @@ struct vsync_info {
 
 #define to_dpu_kms(x) container_of(x, struct dpu_kms, base)
 
-/* get struct msm_kms * from drm_device * */
-#define ddev_to_msm_kms(D) ((D) && (D)->dev_private ? \
-               ((struct msm_drm_private *)((D)->dev_private))->kms : NULL)
-
 /**
  * Debugfs functions - extra helper functions for debugfs support
  *
index 8d24b79..991f4c8 100644 (file)
@@ -154,10 +154,6 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
        u32 ot_lim;
        int ret, i;
 
-       if (!dpu_kms) {
-               DPU_ERROR("invalid arguments\n");
-               return;
-       }
        mdp = dpu_kms->hw_mdp;
 
        for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
@@ -214,7 +210,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
        const struct dpu_vbif_qos_tbl *qos_tbl;
        int i;
 
-       if (!dpu_kms || !params || !dpu_kms->hw_mdp) {
+       if (!params || !dpu_kms->hw_mdp) {
                DPU_ERROR("invalid arguments\n");
                return;
        }
index 50711cc..dda0543 100644 (file)
@@ -157,10 +157,6 @@ static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
        }
 }
 
-static const char * const iommu_ports[] = {
-       "mdp_port0_cb0", "mdp_port1_cb0",
-};
-
 static void mdp4_destroy(struct msm_kms *kms)
 {
        struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
@@ -172,8 +168,7 @@ static void mdp4_destroy(struct msm_kms *kms)
        drm_gem_object_put_unlocked(mdp4_kms->blank_cursor_bo);
 
        if (aspace) {
-               aspace->mmu->funcs->detach(aspace->mmu,
-                               iommu_ports, ARRAY_SIZE(iommu_ports));
+               aspace->mmu->funcs->detach(aspace->mmu);
                msm_gem_address_space_put(aspace);
        }
 
@@ -524,8 +519,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
 
                kms->aspace = aspace;
 
-               ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
-                               ARRAY_SIZE(iommu_ports));
+               ret = aspace->mmu->funcs->attach(aspace->mmu);
                if (ret)
                        goto fail;
        } else {
index f6e71ff..1f48f64 100644 (file)
@@ -14,7 +14,7 @@ struct mdp5_cfg_handler {
 /* mdp5_cfg must be exposed (used in mdp5.xml.h) */
 const struct mdp5_cfg_hw *mdp5_cfg = NULL;
 
-const struct mdp5_cfg_hw msm8x74v1_config = {
+static const struct mdp5_cfg_hw msm8x74v1_config = {
        .name = "msm8x74v1",
        .mdp = {
                .count = 1,
@@ -98,7 +98,7 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
        .max_clk = 200000000,
 };
 
-const struct mdp5_cfg_hw msm8x74v2_config = {
+static const struct mdp5_cfg_hw msm8x74v2_config = {
        .name = "msm8x74",
        .mdp = {
                .count = 1,
@@ -180,7 +180,7 @@ const struct mdp5_cfg_hw msm8x74v2_config = {
        .max_clk = 200000000,
 };
 
-const struct mdp5_cfg_hw apq8084_config = {
+static const struct mdp5_cfg_hw apq8084_config = {
        .name = "apq8084",
        .mdp = {
                .count = 1,
@@ -275,7 +275,7 @@ const struct mdp5_cfg_hw apq8084_config = {
        .max_clk = 320000000,
 };
 
-const struct mdp5_cfg_hw msm8x16_config = {
+static const struct mdp5_cfg_hw msm8x16_config = {
        .name = "msm8x16",
        .mdp = {
                .count = 1,
@@ -342,7 +342,7 @@ const struct mdp5_cfg_hw msm8x16_config = {
        .max_clk = 320000000,
 };
 
-const struct mdp5_cfg_hw msm8x94_config = {
+static const struct mdp5_cfg_hw msm8x94_config = {
        .name = "msm8x94",
        .mdp = {
                .count = 1,
@@ -437,7 +437,7 @@ const struct mdp5_cfg_hw msm8x94_config = {
        .max_clk = 400000000,
 };
 
-const struct mdp5_cfg_hw msm8x96_config = {
+static const struct mdp5_cfg_hw msm8x96_config = {
        .name = "msm8x96",
        .mdp = {
                .count = 1,
@@ -545,7 +545,104 @@ const struct mdp5_cfg_hw msm8x96_config = {
        .max_clk = 412500000,
 };
 
-const struct mdp5_cfg_hw msm8917_config = {
+const struct mdp5_cfg_hw msm8x76_config = {
+       .name = "msm8x76",
+       .mdp = {
+               .count = 1,
+               .caps = MDP_CAP_SMP |
+                       MDP_CAP_DSC |
+                       MDP_CAP_SRC_SPLIT |
+                       0,
+       },
+       .ctl = {
+               .count = 3,
+               .base = { 0x01000, 0x01200, 0x01400 },
+               .flush_hw_mask = 0xffffffff,
+       },
+       .smp = {
+               .mmb_count = 10,
+               .mmb_size = 10240,
+               .clients = {
+                       [SSPP_VIG0] = 1, [SSPP_VIG1] = 9,
+                       [SSPP_DMA0] = 4,
+                       [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+               },
+       },
+       .pipe_vig = {
+               .count = 2,
+               .base = { 0x04000, 0x06000 },
+               .caps = MDP_PIPE_CAP_HFLIP      |
+                       MDP_PIPE_CAP_VFLIP      |
+                       MDP_PIPE_CAP_SCALE      |
+                       MDP_PIPE_CAP_CSC        |
+                       MDP_PIPE_CAP_DECIMATION |
+                       MDP_PIPE_CAP_SW_PIX_EXT |
+                       0,
+       },
+       .pipe_rgb = {
+               .count = 2,
+               .base = { 0x14000, 0x16000 },
+               .caps = MDP_PIPE_CAP_HFLIP      |
+                       MDP_PIPE_CAP_VFLIP      |
+                       MDP_PIPE_CAP_DECIMATION |
+                       MDP_PIPE_CAP_SW_PIX_EXT |
+                       0,
+       },
+       .pipe_dma = {
+               .count = 1,
+               .base = { 0x24000 },
+               .caps = MDP_PIPE_CAP_HFLIP      |
+                       MDP_PIPE_CAP_VFLIP      |
+                       MDP_PIPE_CAP_SW_PIX_EXT |
+                       0,
+       },
+       .pipe_cursor = {
+               .count = 1,
+               .base = { 0x440DC },
+               .caps = MDP_PIPE_CAP_HFLIP      |
+                       MDP_PIPE_CAP_VFLIP      |
+                       MDP_PIPE_CAP_SW_PIX_EXT |
+                       MDP_PIPE_CAP_CURSOR     |
+                       0,
+       },
+       .lm = {
+               .count = 2,
+               .base = { 0x44000, 0x45000 },
+               .instances = {
+                               { .id = 0, .pp = 0, .dspp = 0,
+                                 .caps = MDP_LM_CAP_DISPLAY, },
+                               { .id = 1, .pp = -1, .dspp = -1,
+                                 .caps = MDP_LM_CAP_WB },
+                            },
+               .nb_stages = 8,
+               .max_width = 2560,
+               .max_height = 0xFFFF,
+       },
+       .dspp = {
+               .count = 1,
+               .base = { 0x54000 },
+
+       },
+       .pp = {
+               .count = 3,
+               .base = { 0x70000, 0x70800, 0x72000 },
+       },
+       .dsc = {
+               .count = 2,
+               .base = { 0x80000, 0x80400 },
+       },
+       .intf = {
+               .base = { 0x6a000, 0x6a800, 0x6b000 },
+               .connect = {
+                       [0] = INTF_DISABLED,
+                       [1] = INTF_DSI,
+                       [2] = INTF_DSI,
+               },
+       },
+       .max_clk = 360000000,
+};
+
+static const struct mdp5_cfg_hw msm8917_config = {
        .name = "msm8917",
        .mdp = {
                .count = 1,
@@ -630,7 +727,7 @@ const struct mdp5_cfg_hw msm8917_config = {
        .max_clk = 320000000,
 };
 
-const struct mdp5_cfg_hw msm8998_config = {
+static const struct mdp5_cfg_hw msm8998_config = {
        .name = "msm8998",
        .mdp = {
                .count = 1,
@@ -745,6 +842,7 @@ static const struct mdp5_cfg_handler cfg_handlers_v1[] = {
        { .revision = 6, .config = { .hw = &msm8x16_config } },
        { .revision = 9, .config = { .hw = &msm8x94_config } },
        { .revision = 7, .config = { .hw = &msm8x96_config } },
+       { .revision = 11, .config = { .hw = &msm8x76_config } },
        { .revision = 15, .config = { .hw = &msm8917_config } },
 };
 
index eb0b4b7..05cc04f 100644 (file)
@@ -214,7 +214,6 @@ static void blend_setup(struct drm_crtc *crtc)
        struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
        struct mdp5_kms *mdp5_kms = get_kms(crtc);
        struct drm_plane *plane;
-       const struct mdp5_cfg_hw *hw_cfg;
        struct mdp5_plane_state *pstate, *pstates[STAGE_MAX + 1] = {NULL};
        const struct mdp_format *format;
        struct mdp5_hw_mixer *mixer = pipeline->mixer;
@@ -232,8 +231,6 @@ static void blend_setup(struct drm_crtc *crtc)
        u32 val;
 #define blender(stage) ((stage) - STAGE0)
 
-       hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
-
        spin_lock_irqsave(&mdp5_crtc->lm_lock, flags);
 
        /* ctl could be released already when we are shutting down: */
index 91cd76a..e43ecd4 100644 (file)
 #include "msm_mmu.h"
 #include "mdp5_kms.h"
 
-static const char *iommu_ports[] = {
-               "mdp_0",
-};
-
 static int mdp5_hw_init(struct msm_kms *kms)
 {
        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -233,8 +229,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
                mdp5_pipe_destroy(mdp5_kms->hwpipes[i]);
 
        if (aspace) {
-               aspace->mmu->funcs->detach(aspace->mmu,
-                               iommu_ports, ARRAY_SIZE(iommu_ports));
+               aspace->mmu->funcs->detach(aspace->mmu);
                msm_gem_address_space_put(aspace);
        }
 }
@@ -314,6 +309,10 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms)
        mdp5_kms->enable_count--;
        WARN_ON(mdp5_kms->enable_count < 0);
 
+       if (mdp5_kms->tbu_rt_clk)
+               clk_disable_unprepare(mdp5_kms->tbu_rt_clk);
+       if (mdp5_kms->tbu_clk)
+               clk_disable_unprepare(mdp5_kms->tbu_clk);
        clk_disable_unprepare(mdp5_kms->ahb_clk);
        clk_disable_unprepare(mdp5_kms->axi_clk);
        clk_disable_unprepare(mdp5_kms->core_clk);
@@ -334,6 +333,10 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
        clk_prepare_enable(mdp5_kms->core_clk);
        if (mdp5_kms->lut_clk)
                clk_prepare_enable(mdp5_kms->lut_clk);
+       if (mdp5_kms->tbu_clk)
+               clk_prepare_enable(mdp5_kms->tbu_clk);
+       if (mdp5_kms->tbu_rt_clk)
+               clk_prepare_enable(mdp5_kms->tbu_rt_clk);
 
        return 0;
 }
@@ -466,14 +469,11 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 {
        struct drm_device *dev = mdp5_kms->dev;
        struct msm_drm_private *priv = dev->dev_private;
-       const struct mdp5_cfg_hw *hw_cfg;
        unsigned int num_crtcs;
        int i, ret, pi = 0, ci = 0;
        struct drm_plane *primary[MAX_BASES] = { NULL };
        struct drm_plane *cursor[MAX_BASES] = { NULL };
 
-       hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
-
        /*
         * Construct encoders and modeset initialize connector devices
         * for each external display interface.
@@ -737,8 +737,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 
                kms->aspace = aspace;
 
-               ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
-                               ARRAY_SIZE(iommu_ports));
+               ret = aspace->mmu->funcs->attach(aspace->mmu);
                if (ret) {
                        DRM_DEV_ERROR(&pdev->dev, "failed to attach iommu: %d\n",
                                ret);
@@ -974,6 +973,8 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 
        /* optional clocks: */
        get_clk(pdev, &mdp5_kms->lut_clk, "lut", false);
+       get_clk(pdev, &mdp5_kms->tbu_clk, "tbu", false);
+       get_clk(pdev, &mdp5_kms->tbu_rt_clk, "tbu_rt", false);
 
        /* we need to set a default rate before enabling.  Set a safe
         * rate first, then figure out hw revision, and then set a
index d1bf4fd..1288667 100644 (file)
@@ -53,6 +53,8 @@ struct mdp5_kms {
        struct clk *ahb_clk;
        struct clk *core_clk;
        struct clk *lut_clk;
+       struct clk *tbu_clk;
+       struct clk *tbu_rt_clk;
        struct clk *vsync_clk;
 
        /*
index b31cfb5..d7fa2c4 100644 (file)
@@ -121,7 +121,6 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
        struct mdp5_kms *mdp5_kms = get_kms(smp);
        int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg);
        int i, hsub, nplanes, nlines;
-       u32 fmt = format->base.pixel_format;
        uint32_t blkcfg = 0;
 
        nplanes = info->num_planes;
@@ -135,7 +134,6 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
         * them together, writes to SMP using a single client.
         */
        if ((rev > 0) && (format->chroma_sample > CHROMA_FULL)) {
-               fmt = DRM_FORMAT_NV24;
                nplanes = 2;
 
                /* if decimation is enabled, HW decimates less on the
index b7b7c1a..86ad3fd 100644 (file)
@@ -66,6 +66,26 @@ static const struct msm_dsi_config msm8916_dsi_cfg = {
        .num_dsi = 1,
 };
 
+static const char * const dsi_8976_bus_clk_names[] = {
+       "mdp_core", "iface", "bus",
+};
+
+static const struct msm_dsi_config msm8976_dsi_cfg = {
+       .io_offset = DSI_6G_REG_SHIFT,
+       .reg_cfg = {
+               .num = 3,
+               .regs = {
+                       {"gdsc", -1, -1},
+                       {"vdda", 100000, 100},  /* 1.2 V */
+                       {"vddio", 100000, 100}, /* 1.8 V */
+               },
+       },
+       .bus_clk_names = dsi_8976_bus_clk_names,
+       .num_bus_clks = ARRAY_SIZE(dsi_8976_bus_clk_names),
+       .io_start = { 0x1a94000, 0x1a96000 },
+       .num_dsi = 2,
+};
+
 static const struct msm_dsi_config msm8994_dsi_cfg = {
        .io_offset = DSI_6G_REG_SHIFT,
        .reg_cfg = {
@@ -147,7 +167,7 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
        .num_dsi = 2,
 };
 
-const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
+static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
        .link_clk_enable = dsi_link_clk_enable_v2,
        .link_clk_disable = dsi_link_clk_disable_v2,
        .clk_init_ver = dsi_clk_init_v2,
@@ -158,7 +178,7 @@ const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
        .calc_clk_rate = dsi_calc_clk_rate_v2,
 };
 
-const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
+static const struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
        .link_clk_enable = dsi_link_clk_enable_6g,
        .link_clk_disable = dsi_link_clk_disable_6g,
        .clk_init_ver = NULL,
@@ -169,7 +189,7 @@ const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
        .calc_clk_rate = dsi_calc_clk_rate_6g,
 };
 
-const static struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
+static const struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
        .link_clk_enable = dsi_link_clk_enable_6g,
        .link_clk_disable = dsi_link_clk_disable_6g,
        .clk_init_ver = dsi_clk_init_6g_v2,
@@ -197,6 +217,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
                &msm8916_dsi_cfg, &msm_dsi_6g_host_ops},
        {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
                &msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
+       {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_2,
+               &msm8976_dsi_cfg, &msm_dsi_6g_host_ops},
        {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_0,
                &msm8998_dsi_cfg, &msm_dsi_6g_v2_host_ops},
        {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
index e2b7a7d..50a37ce 100644 (file)
@@ -17,6 +17,7 @@
 #define MSM_DSI_6G_VER_MINOR_V1_3      0x10030000
 #define MSM_DSI_6G_VER_MINOR_V1_3_1    0x10030001
 #define MSM_DSI_6G_VER_MINOR_V1_4_1    0x10040001
+#define MSM_DSI_6G_VER_MINOR_V1_4_2    0x10040002
 #define MSM_DSI_6G_VER_MINOR_V2_2_0    0x20000000
 #define MSM_DSI_6G_VER_MINOR_V2_2_1    0x20020001
 
index 1e7b1be..458cec8 100644 (file)
@@ -1293,14 +1293,13 @@ static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
 static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host,
                        u8 *buf, int rx_byte, int pkt_size)
 {
-       u32 *lp, *temp, data;
+       u32 *temp, data;
        int i, j = 0, cnt;
        u32 read_cnt;
        u8 reg[16];
        int repeated_bytes = 0;
        int buf_offset = buf - msm_host->rx_buf;
 
-       lp = (u32 *)buf;
        temp = (u32 *)reg;
        cnt = (rx_byte + 3) >> 2;
        if (cnt > 4)
index 3522863..b0cfa67 100644 (file)
@@ -145,7 +145,7 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
 {
        const unsigned long bit_rate = clk_req->bitclk_rate;
        const unsigned long esc_rate = clk_req->escclk_rate;
-       s32 ui, ui_x8, lpx;
+       s32 ui, ui_x8;
        s32 tmax, tmin;
        s32 pcnt0 = 50;
        s32 pcnt1 = 50;
@@ -175,7 +175,6 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
 
        ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
        ui_x8 = ui << 3;
-       lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
 
        temp = S_DIV_ROUND_UP(38 * coeff - val_ckln * ui, ui_x8);
        tmin = max_t(s32, temp, 0);
@@ -262,7 +261,7 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
 {
        const unsigned long bit_rate = clk_req->bitclk_rate;
        const unsigned long esc_rate = clk_req->escclk_rate;
-       s32 ui, ui_x8, lpx;
+       s32 ui, ui_x8;
        s32 tmax, tmin;
        s32 pcnt0 = 50;
        s32 pcnt1 = 50;
@@ -284,7 +283,6 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
 
        ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
        ui_x8 = ui << 3;
-       lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
 
        temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
        tmin = max_t(s32, temp, 0);
@@ -485,6 +483,8 @@ static const struct of_device_id dsi_phy_dt_match[] = {
 #ifdef CONFIG_DRM_MSM_DSI_28NM_PHY
        { .compatible = "qcom,dsi-phy-28nm-hpm",
          .data = &dsi_phy_28nm_hpm_cfgs },
+       { .compatible = "qcom,dsi-phy-28nm-hpm-fam-b",
+         .data = &dsi_phy_28nm_hpm_famb_cfgs },
        { .compatible = "qcom,dsi-phy-28nm-lp",
          .data = &dsi_phy_28nm_lp_cfgs },
 #endif
index c4069ce..24b294e 100644 (file)
@@ -40,6 +40,7 @@ struct msm_dsi_phy_cfg {
 };
 
 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs;
index b3f678f..c3c580c 100644 (file)
@@ -39,15 +39,10 @@ static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
                DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
 }
 
-static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
+static void dsi_28nm_phy_regulator_enable_dcdc(struct msm_dsi_phy *phy)
 {
        void __iomem *base = phy->reg_base;
 
-       if (!enable) {
-               dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
-               return;
-       }
-
        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1);
        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0);
@@ -56,6 +51,39 @@ static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9);
        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7);
        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
+       dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
+}
+
+static void dsi_28nm_phy_regulator_enable_ldo(struct msm_dsi_phy *phy)
+{
+       void __iomem *base = phy->reg_base;
+
+       dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
+       dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
+       dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0x7);
+       dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
+       dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x1);
+       dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x1);
+       dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
+
+       if (phy->cfg->type == MSM_DSI_PHY_28NM_LP)
+               dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x05);
+       else
+               dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x0d);
+}
+
+static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
+{
+       if (!enable) {
+               dsi_phy_write(phy->reg_base +
+                             REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
+               return;
+       }
+
+       if (phy->regulator_ldo_mode)
+               dsi_28nm_phy_regulator_enable_ldo(phy);
+       else
+               dsi_28nm_phy_regulator_enable_dcdc(phy);
 }
 
 static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
@@ -77,8 +105,6 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
 
        dsi_28nm_phy_regulator_ctrl(phy, true);
 
-       dsi_phy_write(base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
-
        dsi_28nm_dphy_set_timing(phy, timing);
 
        dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00);
@@ -142,6 +168,24 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = {
        .num_dsi_phy = 2,
 };
 
+const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = {
+       .type = MSM_DSI_PHY_28NM_HPM,
+       .src_pll_truthtable = { {true, true}, {false, true} },
+       .reg_cfg = {
+               .num = 1,
+               .regs = {
+                       {"vddio", 100000, 100},
+               },
+       },
+       .ops = {
+               .enable = dsi_28nm_phy_enable,
+               .disable = dsi_28nm_phy_disable,
+               .init = msm_dsi_phy_init_common,
+       },
+       .io_start = { 0x1a94400, 0x1a96400 },
+       .num_dsi_phy = 2,
+};
+
 const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = {
        .type = MSM_DSI_PHY_28NM_LP,
        .src_pll_truthtable = { {true, true}, {true, true} },
index 1697e61..8a38d4b 100644 (file)
@@ -29,8 +29,12 @@ static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy)
                reg = devm_regulator_get(dev, cfg->reg_names[i]);
                if (IS_ERR(reg)) {
                        ret = PTR_ERR(reg);
-                       DRM_DEV_ERROR(dev, "failed to get phy regulator: %s (%d)\n",
-                               cfg->reg_names[i], ret);
+                       if (ret != -EPROBE_DEFER) {
+                               DRM_DEV_ERROR(dev,
+                                             "failed to get phy regulator: %s (%d)\n",
+                                             cfg->reg_names[i], ret);
+                       }
+
                        return ret;
                }
 
index a052364..18f3a5c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/pm_opp.h>
 #include <linux/devfreq.h>
 #include <linux/devcoredump.h>
+#include <linux/sched/task.h>
 
 /*
  * Power Management:
@@ -838,7 +839,7 @@ msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
                return ERR_CAST(aspace);
        }
 
-       ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0);
+       ret = aspace->mmu->funcs->attach(aspace->mmu);
        if (ret) {
                msm_gem_address_space_put(aspace);
                return ERR_PTR(ret);
@@ -995,8 +996,7 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
        msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace, false);
 
        if (!IS_ERR_OR_NULL(gpu->aspace)) {
-               gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
-                       NULL, 0);
+               gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu);
                msm_gem_address_space_put(gpu->aspace);
        }
 }
index 34f643a..34980d8 100644 (file)
@@ -21,14 +21,12 @@ struct msm_gpummu {
 #define GPUMMU_PAGE_SIZE SZ_4K
 #define TABLE_SIZE (sizeof(uint32_t) * GPUMMU_VA_RANGE / GPUMMU_PAGE_SIZE)
 
-static int msm_gpummu_attach(struct msm_mmu *mmu, const char * const *names,
-               int cnt)
+static int msm_gpummu_attach(struct msm_mmu *mmu)
 {
        return 0;
 }
 
-static void msm_gpummu_detach(struct msm_mmu *mmu, const char * const *names,
-               int cnt)
+static void msm_gpummu_detach(struct msm_mmu *mmu)
 {
 }
 
index 8c95c31..ad58cfe 100644 (file)
@@ -23,16 +23,14 @@ static int msm_fault_handler(struct iommu_domain *domain, struct device *dev,
        return 0;
 }
 
-static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names,
-                           int cnt)
+static int msm_iommu_attach(struct msm_mmu *mmu)
 {
        struct msm_iommu *iommu = to_msm_iommu(mmu);
 
        return iommu_attach_device(iommu->domain, mmu->dev);
 }
 
-static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names,
-                            int cnt)
+static void msm_iommu_detach(struct msm_mmu *mmu)
 {
        struct msm_iommu *iommu = to_msm_iommu(mmu);
 
index 871d563..67a623f 100644 (file)
@@ -10,8 +10,8 @@
 #include <linux/iommu.h>
 
 struct msm_mmu_funcs {
-       int (*attach)(struct msm_mmu *mmu, const char * const *names, int cnt);
-       void (*detach)(struct msm_mmu *mmu, const char * const *names, int cnt);
+       int (*attach)(struct msm_mmu *mmu);
+       void (*detach)(struct msm_mmu *mmu);
        int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
                        unsigned len, int prot);
        int (*unmap)(struct msm_mmu *mmu, uint64_t iova, unsigned len);
index c7832a9..af7ceb2 100644 (file)
@@ -298,7 +298,7 @@ void msm_rd_debugfs_cleanup(struct msm_drm_private *priv)
 
 static void snapshot_buf(struct msm_rd_state *rd,
                struct msm_gem_submit *submit, int idx,
-               uint64_t iova, uint32_t size)
+               uint64_t iova, uint32_t size, bool full)
 {
        struct msm_gem_object *obj = submit->bos[idx].obj;
        unsigned offset = 0;
@@ -318,6 +318,9 @@ static void snapshot_buf(struct msm_rd_state *rd,
        rd_write_section(rd, RD_GPUADDR,
                        (uint32_t[3]){ iova, size, iova >> 32 }, 12);
 
+       if (!full)
+               return;
+
        /* But only dump the contents of buffers marked READ */
        if (!(submit->bos[idx].flags & MSM_SUBMIT_BO_READ))
                return;
@@ -381,18 +384,21 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
        rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4));
 
        for (i = 0; i < submit->nr_bos; i++)
-               if (should_dump(submit, i))
-                       snapshot_buf(rd, submit, i, 0, 0);
+               snapshot_buf(rd, submit, i, 0, 0, should_dump(submit, i));
 
        for (i = 0; i < submit->nr_cmds; i++) {
-               uint64_t iova = submit->cmd[i].iova;
                uint32_t szd  = submit->cmd[i].size; /* in dwords */
 
                /* snapshot cmdstream bo's (if we haven't already): */
                if (!should_dump(submit, i)) {
                        snapshot_buf(rd, submit, submit->cmd[i].idx,
-                                       submit->cmd[i].iova, szd * 4);
+                                       submit->cmd[i].iova, szd * 4, true);
                }
+       }
+
+       for (i = 0; i < submit->nr_cmds; i++) {
+               uint64_t iova = submit->cmd[i].iova;
+               uint32_t szd  = submit->cmd[i].size; /* in dwords */
 
                switch (submit->cmd[i].type) {
                case MSM_SUBMIT_CMD_IB_TARGET_BUF:
index 43df86c..24f7700 100644 (file)
@@ -114,6 +114,7 @@ struct nv50_head_atom {
                u8 nhsync:1;
                u8 nvsync:1;
                u8 depth:4;
+               u8 bpc;
        } or;
 
        /* Currently only used for MST */
index 549486f..63425e2 100644 (file)
@@ -326,9 +326,9 @@ nv50_outp_atomic_check_view(struct drm_encoder *encoder,
                         * same size as the native one (e.g. different
                         * refresh rate)
                         */
-                       if (adjusted_mode->hdisplay == native_mode->hdisplay &&
-                           adjusted_mode->vdisplay == native_mode->vdisplay &&
-                           adjusted_mode->type & DRM_MODE_TYPE_DRIVER)
+                       if (mode->hdisplay == native_mode->hdisplay &&
+                           mode->vdisplay == native_mode->vdisplay &&
+                           mode->type & DRM_MODE_TYPE_DRIVER)
                                break;
                        mode = native_mode;
                        asyc->scaler.full = true;
@@ -353,10 +353,20 @@ nv50_outp_atomic_check(struct drm_encoder *encoder,
                       struct drm_crtc_state *crtc_state,
                       struct drm_connector_state *conn_state)
 {
-       struct nouveau_connector *nv_connector =
-               nouveau_connector(conn_state->connector);
-       return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
-                                          nv_connector->native_mode);
+       struct drm_connector *connector = conn_state->connector;
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
+       int ret;
+
+       ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
+                                         nv_connector->native_mode);
+       if (ret)
+               return ret;
+
+       if (crtc_state->mode_changed || crtc_state->connectors_changed)
+               asyh->or.bpc = connector->display_info.bpc;
+
+       return 0;
 }
 
 /******************************************************************************
@@ -770,32 +780,54 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
        struct nv50_mstm *mstm = mstc->mstm;
        struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
        int slots;
+       int ret;
+
+       ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
+                                         mstc->native);
+       if (ret)
+               return ret;
+
+       if (!crtc_state->mode_changed && !crtc_state->connectors_changed)
+               return 0;
+
+       /*
+        * When restoring duplicated states, we need to make sure that the bw
+        * remains the same and avoid recalculating it, as the connector's bpc
+        * may have changed after the state was duplicated
+        */
+       if (!state->duplicated) {
+               const int clock = crtc_state->adjusted_mode.clock;
 
-       if (crtc_state->mode_changed || crtc_state->connectors_changed) {
                /*
-                * When restoring duplicated states, we need to make sure that
-                * the bw remains the same and avoid recalculating it, as the
-                * connector's bpc may have changed after the state was
-                * duplicated
+                * XXX: Since we don't use HDR in userspace quite yet, limit
+                * the bpc to 8 to save bandwidth on the topology. In the
+                * future, we'll want to properly fix this by dynamically
+                * selecting the highest possible bpc that would fit in the
+                * topology
                 */
-               if (!state->duplicated) {
-                       const int bpp = connector->display_info.bpc * 3;
-                       const int clock = crtc_state->adjusted_mode.clock;
+               asyh->or.bpc = min(connector->display_info.bpc, 8U);
+               asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3);
+       }
 
-                       asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, bpp);
-               }
+       slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, mstc->port,
+                                             asyh->dp.pbn);
+       if (slots < 0)
+               return slots;
 
-               slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
-                                                     mstc->port,
-                                                     asyh->dp.pbn);
-               if (slots < 0)
-                       return slots;
+       asyh->dp.tu = slots;
 
-               asyh->dp.tu = slots;
-       }
+       return 0;
+}
 
-       return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
-                                          mstc->native);
+static u8
+nv50_dp_bpc_to_depth(unsigned int bpc)
+{
+       switch (bpc) {
+       case  6: return 0x2;
+       case  8: return 0x5;
+       case 10: /* fall-through */
+       default: return 0x6;
+       }
 }
 
 static void
@@ -808,7 +840,7 @@ nv50_msto_enable(struct drm_encoder *encoder)
        struct nv50_mstm *mstm = NULL;
        struct drm_connector *connector;
        struct drm_connector_list_iter conn_iter;
-       u8 proto, depth;
+       u8 proto;
        bool r;
 
        drm_connector_list_iter_begin(encoder->dev, &conn_iter);
@@ -837,14 +869,8 @@ nv50_msto_enable(struct drm_encoder *encoder)
        else
                proto = 0x9;
 
-       switch (mstc->connector.display_info.bpc) {
-       case  6: depth = 0x2; break;
-       case  8: depth = 0x5; break;
-       case 10:
-       default: depth = 0x6; break;
-       }
-
-       mstm->outp->update(mstm->outp, head->base.index, armh, proto, depth);
+       mstm->outp->update(mstm->outp, head->base.index, armh, proto,
+                          nv50_dp_bpc_to_depth(armh->or.bpc));
 
        msto->head = head;
        msto->mstc = mstc;
@@ -1498,20 +1524,14 @@ nv50_sor_enable(struct drm_encoder *encoder)
                                        lvds.lvds.script |= 0x0200;
                        }
 
-                       if (nv_connector->base.display_info.bpc == 8)
+                       if (asyh->or.bpc == 8)
                                lvds.lvds.script |= 0x0200;
                }
 
                nvif_mthd(&disp->disp->object, 0, &lvds, sizeof(lvds));
                break;
        case DCB_OUTPUT_DP:
-               if (nv_connector->base.display_info.bpc == 6)
-                       depth = 0x2;
-               else
-               if (nv_connector->base.display_info.bpc == 8)
-                       depth = 0x5;
-               else
-                       depth = 0x6;
+               depth = nv50_dp_bpc_to_depth(asyh->or.bpc);
 
                if (nv_encoder->link & 1)
                        proto = 0x8;
@@ -1662,7 +1682,7 @@ nv50_pior_enable(struct drm_encoder *encoder)
        nv50_outp_acquire(nv_encoder);
 
        nv_connector = nouveau_encoder_connector_get(nv_encoder);
-       switch (nv_connector->base.display_info.bpc) {
+       switch (asyh->or.bpc) {
        case 10: asyh->or.depth = 0x6; break;
        case  8: asyh->or.depth = 0x5; break;
        case  6: asyh->or.depth = 0x2; break;
index 71c23bf..c9692df 100644 (file)
@@ -81,18 +81,17 @@ nv50_head_atomic_check_dither(struct nv50_head_atom *armh,
                              struct nv50_head_atom *asyh,
                              struct nouveau_conn_atom *asyc)
 {
-       struct drm_connector *connector = asyc->state.connector;
        u32 mode = 0x00;
 
        if (asyc->dither.mode == DITHERING_MODE_AUTO) {
-               if (asyh->base.depth > connector->display_info.bpc * 3)
+               if (asyh->base.depth > asyh->or.bpc * 3)
                        mode = DITHERING_MODE_DYNAMIC2X2;
        } else {
                mode = asyc->dither.mode;
        }
 
        if (asyc->dither.depth == DITHERING_DEPTH_AUTO) {
-               if (connector->display_info.bpc >= 8)
+               if (asyh->or.bpc >= 8)
                        mode |= DITHERING_DEPTH_8BPC;
        } else {
                mode |= asyc->dither.depth;
index 5b41358..9a9a7f5 100644 (file)
@@ -245,14 +245,22 @@ nouveau_conn_atomic_duplicate_state(struct drm_connector *connector)
 void
 nouveau_conn_reset(struct drm_connector *connector)
 {
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
        struct nouveau_conn_atom *asyc;
 
-       if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL))))
-               return;
+       if (drm_drv_uses_atomic_modeset(connector->dev)) {
+               if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL))))
+                       return;
+
+               if (connector->state)
+                       nouveau_conn_atomic_destroy_state(connector,
+                                                         connector->state);
+
+               __drm_atomic_helper_connector_reset(connector, &asyc->state);
+       } else {
+               asyc = &nv_connector->properties_state;
+       }
 
-       if (connector->state)
-               nouveau_conn_atomic_destroy_state(connector, connector->state);
-       __drm_atomic_helper_connector_reset(connector, &asyc->state);
        asyc->dither.mode = DITHERING_MODE_AUTO;
        asyc->dither.depth = DITHERING_DEPTH_AUTO;
        asyc->scaler.mode = DRM_MODE_SCALE_NONE;
@@ -276,8 +284,14 @@ void
 nouveau_conn_attach_properties(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state);
        struct nouveau_display *disp = nouveau_display(dev);
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct nouveau_conn_atom *armc;
+
+       if (drm_drv_uses_atomic_modeset(connector->dev))
+               armc = nouveau_conn_atom(connector->state);
+       else
+               armc = &nv_connector->properties_state;
 
        /* Init DVI-I specific properties. */
        if (connector->connector_type == DRM_MODE_CONNECTOR_DVII)
@@ -748,9 +762,9 @@ static int
 nouveau_connector_set_property(struct drm_connector *connector,
                               struct drm_property *property, uint64_t value)
 {
-       struct nouveau_conn_atom *asyc = nouveau_conn_atom(connector->state);
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
        struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
+       struct nouveau_conn_atom *asyc = &nv_connector->properties_state;
        struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
        int ret;
 
index f43a8d6..de84fb4 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <nvif/notify.h>
 
+#include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_dp_helper.h>
@@ -44,6 +45,60 @@ struct dcb_output;
 struct nouveau_backlight;
 #endif
 
+#define nouveau_conn_atom(p)                                                   \
+       container_of((p), struct nouveau_conn_atom, state)
+
+struct nouveau_conn_atom {
+       struct drm_connector_state state;
+
+       struct {
+               /* The enum values specifically defined here match nv50/gf119
+                * hw values, and the code relies on this.
+                */
+               enum {
+                       DITHERING_MODE_OFF = 0x00,
+                       DITHERING_MODE_ON = 0x01,
+                       DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON,
+                       DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON,
+                       DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON,
+                       DITHERING_MODE_AUTO
+               } mode;
+               enum {
+                       DITHERING_DEPTH_6BPC = 0x00,
+                       DITHERING_DEPTH_8BPC = 0x02,
+                       DITHERING_DEPTH_AUTO
+               } depth;
+       } dither;
+
+       struct {
+               int mode;       /* DRM_MODE_SCALE_* */
+               struct {
+                       enum {
+                               UNDERSCAN_OFF,
+                               UNDERSCAN_ON,
+                               UNDERSCAN_AUTO,
+                       } mode;
+                       u32 hborder;
+                       u32 vborder;
+               } underscan;
+               bool full;
+       } scaler;
+
+       struct {
+               int color_vibrance;
+               int vibrant_hue;
+       } procamp;
+
+       union {
+               struct {
+                       bool dither:1;
+                       bool scaler:1;
+                       bool procamp:1;
+               };
+               u8 mask;
+       } set;
+};
+
 struct nouveau_connector {
        struct drm_connector base;
        enum dcb_connector_type type;
@@ -63,6 +118,12 @@ struct nouveau_connector {
 #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
        struct nouveau_backlight *backlight;
 #endif
+       /*
+        * Our connector property code expects a nouveau_conn_atom struct
+        * even on pre-nv50 where we do not support atomic. This embedded
+        * version gets used in the non atomic modeset case.
+        */
+       struct nouveau_conn_atom properties_state;
 };
 
 static inline struct nouveau_connector *nouveau_connector(
@@ -121,61 +182,6 @@ extern int nouveau_ignorelid;
 extern int nouveau_duallink;
 extern int nouveau_hdmimhz;
 
-#include <drm/drm_crtc.h>
-#define nouveau_conn_atom(p)                                                   \
-       container_of((p), struct nouveau_conn_atom, state)
-
-struct nouveau_conn_atom {
-       struct drm_connector_state state;
-
-       struct {
-               /* The enum values specifically defined here match nv50/gf119
-                * hw values, and the code relies on this.
-                */
-               enum {
-                       DITHERING_MODE_OFF = 0x00,
-                       DITHERING_MODE_ON = 0x01,
-                       DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON,
-                       DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON,
-                       DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON,
-                       DITHERING_MODE_AUTO
-               } mode;
-               enum {
-                       DITHERING_DEPTH_6BPC = 0x00,
-                       DITHERING_DEPTH_8BPC = 0x02,
-                       DITHERING_DEPTH_AUTO
-               } depth;
-       } dither;
-
-       struct {
-               int mode;       /* DRM_MODE_SCALE_* */
-               struct {
-                       enum {
-                               UNDERSCAN_OFF,
-                               UNDERSCAN_ON,
-                               UNDERSCAN_AUTO,
-                       } mode;
-                       u32 hborder;
-                       u32 vborder;
-               } underscan;
-               bool full;
-       } scaler;
-
-       struct {
-               int color_vibrance;
-               int vibrant_hue;
-       } procamp;
-
-       union {
-               struct {
-                       bool dither:1;
-                       bool scaler:1;
-                       bool procamp:1;
-               };
-               u8 mask;
-       } set;
-};
-
 void nouveau_conn_attach_properties(struct drm_connector *);
 void nouveau_conn_reset(struct drm_connector *);
 struct drm_connector_state *
index e518d93..d08ae95 100644 (file)
@@ -843,9 +843,13 @@ fail:
  */
 static void omap_gem_unpin_locked(struct drm_gem_object *obj)
 {
+       struct omap_drm_private *priv = obj->dev->dev_private;
        struct omap_gem_object *omap_obj = to_omap_bo(obj);
        int ret;
 
+       if (omap_gem_is_contiguous(omap_obj) || !priv->has_dmm)
+               return;
+
        if (refcount_dec_and_test(&omap_obj->dma_addr_cnt)) {
                ret = tiler_unpin(omap_obj->block);
                if (ret) {
index 4c4e8a3..536ba93 100644 (file)
@@ -18,15 +18,18 @@ static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev);
 static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
                                   u32 flags)
 {
-       struct panfrost_device *pfdev = dev_get_drvdata(dev);
+       struct dev_pm_opp *opp;
        int err;
 
+       opp = devfreq_recommended_opp(dev, freq, flags);
+       if (IS_ERR(opp))
+               return PTR_ERR(opp);
+       dev_pm_opp_put(opp);
+
        err = dev_pm_opp_set_rate(dev, *freq);
        if (err)
                return err;
 
-       *freq = clk_get_rate(pfdev->clock);
-
        return 0;
 }
 
@@ -60,20 +63,10 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
        return 0;
 }
 
-static int panfrost_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
-{
-       struct panfrost_device *pfdev = platform_get_drvdata(to_platform_device(dev));
-
-       *freq = clk_get_rate(pfdev->clock);
-
-       return 0;
-}
-
 static struct devfreq_dev_profile panfrost_devfreq_profile = {
        .polling_ms = 50, /* ~3 frames */
        .target = panfrost_devfreq_target,
        .get_dev_status = panfrost_devfreq_get_dev_status,
-       .get_cur_freq = panfrost_devfreq_get_cur_freq,
 };
 
 int panfrost_devfreq_init(struct panfrost_device *pfdev)
index 9458dc6..f61364f 100644 (file)
@@ -303,14 +303,17 @@ static int panfrost_ioctl_mmap_bo(struct drm_device *dev, void *data,
        }
 
        /* Don't allow mmapping of heap objects as pages are not pinned. */
-       if (to_panfrost_bo(gem_obj)->is_heap)
-               return -EINVAL;
+       if (to_panfrost_bo(gem_obj)->is_heap) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        ret = drm_gem_create_mmap_offset(gem_obj);
        if (ret == 0)
                args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
-       drm_gem_object_put_unlocked(gem_obj);
 
+out:
+       drm_gem_object_put_unlocked(gem_obj);
        return ret;
 }
 
@@ -347,20 +350,19 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
                return -ENOENT;
        }
 
+       mutex_lock(&pfdev->shrinker_lock);
        args->retained = drm_gem_shmem_madvise(gem_obj, args->madv);
 
        if (args->retained) {
                struct panfrost_gem_object *bo = to_panfrost_bo(gem_obj);
 
-               mutex_lock(&pfdev->shrinker_lock);
-
                if (args->madv == PANFROST_MADV_DONTNEED)
-                       list_add_tail(&bo->base.madv_list, &pfdev->shrinker_list);
+                       list_add_tail(&bo->base.madv_list,
+                                     &pfdev->shrinker_list);
                else if (args->madv == PANFROST_MADV_WILLNEED)
                        list_del_init(&bo->base.madv_list);
-
-               mutex_unlock(&pfdev->shrinker_lock);
        }
+       mutex_unlock(&pfdev->shrinker_lock);
 
        drm_gem_object_put_unlocked(gem_obj);
        return 0;
@@ -443,7 +445,7 @@ panfrost_postclose(struct drm_device *dev, struct drm_file *file)
 {
        struct panfrost_file_priv *panfrost_priv = file->driver_priv;
 
-       panfrost_perfcnt_close(panfrost_priv);
+       panfrost_perfcnt_close(file);
        panfrost_job_close(panfrost_priv);
 
        panfrost_mmu_pgtable_free(panfrost_priv);
index deca0c3..fd766b1 100644 (file)
@@ -19,6 +19,16 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
        struct panfrost_gem_object *bo = to_panfrost_bo(obj);
        struct panfrost_device *pfdev = obj->dev->dev_private;
 
+       /*
+        * Make sure the BO is no longer inserted in the shrinker list before
+        * taking care of the destruction itself. If we don't do that we have a
+        * race condition between this function and what's done in
+        * panfrost_gem_shrinker_scan().
+        */
+       mutex_lock(&pfdev->shrinker_lock);
+       list_del_init(&bo->base.madv_list);
+       mutex_unlock(&pfdev->shrinker_lock);
+
        if (bo->sgts) {
                int i;
                int n_sgt = bo->base.base.size / SZ_2M;
@@ -33,15 +43,10 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
                kfree(bo->sgts);
        }
 
-       mutex_lock(&pfdev->shrinker_lock);
-       if (!list_empty(&bo->base.madv_list))
-               list_del(&bo->base.madv_list);
-       mutex_unlock(&pfdev->shrinker_lock);
-
        drm_gem_shmem_free_object(obj);
 }
 
-static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)
+int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)
 {
        int ret;
        size_t size = obj->size;
@@ -80,7 +85,7 @@ static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_p
        return ret;
 }
 
-static void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
+void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
 {
        struct panfrost_gem_object *bo = to_panfrost_bo(obj);
        struct panfrost_file_priv *priv = file_priv->driver_priv;
index 5092081..4b17e73 100644 (file)
@@ -45,6 +45,10 @@ panfrost_gem_create_with_handle(struct drm_file *file_priv,
                                u32 flags,
                                uint32_t *handle);
 
+int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv);
+void panfrost_gem_close(struct drm_gem_object *obj,
+                       struct drm_file *file_priv);
+
 void panfrost_gem_shrinker_init(struct drm_device *dev);
 void panfrost_gem_shrinker_cleanup(struct drm_device *dev);
 
index 2dba192..2c04e85 100644 (file)
@@ -67,9 +67,10 @@ static int panfrost_perfcnt_dump_locked(struct panfrost_device *pfdev)
 }
 
 static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
-                                         struct panfrost_file_priv *user,
+                                         struct drm_file *file_priv,
                                          unsigned int counterset)
 {
+       struct panfrost_file_priv *user = file_priv->driver_priv;
        struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
        struct drm_gem_shmem_object *bo;
        u32 cfg;
@@ -91,14 +92,14 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
        perfcnt->bo = to_panfrost_bo(&bo->base);
 
        /* Map the perfcnt buf in the address space attached to file_priv. */
-       ret = panfrost_mmu_map(perfcnt->bo);
+       ret = panfrost_gem_open(&perfcnt->bo->base.base, file_priv);
        if (ret)
                goto err_put_bo;
 
        perfcnt->buf = drm_gem_shmem_vmap(&bo->base);
        if (IS_ERR(perfcnt->buf)) {
                ret = PTR_ERR(perfcnt->buf);
-               goto err_put_bo;
+               goto err_close_bo;
        }
 
        /*
@@ -157,14 +158,17 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
 
 err_vunmap:
        drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf);
+err_close_bo:
+       panfrost_gem_close(&perfcnt->bo->base.base, file_priv);
 err_put_bo:
        drm_gem_object_put_unlocked(&bo->base);
        return ret;
 }
 
 static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
-                                          struct panfrost_file_priv *user)
+                                          struct drm_file *file_priv)
 {
+       struct panfrost_file_priv *user = file_priv->driver_priv;
        struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
 
        if (user != perfcnt->user)
@@ -180,6 +184,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
        perfcnt->user = NULL;
        drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf);
        perfcnt->buf = NULL;
+       panfrost_gem_close(&perfcnt->bo->base.base, file_priv);
        drm_gem_object_put_unlocked(&perfcnt->bo->base.base);
        perfcnt->bo = NULL;
        pm_runtime_mark_last_busy(pfdev->dev);
@@ -191,7 +196,6 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
 int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data,
                                  struct drm_file *file_priv)
 {
-       struct panfrost_file_priv *pfile = file_priv->driver_priv;
        struct panfrost_device *pfdev = dev->dev_private;
        struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
        struct drm_panfrost_perfcnt_enable *req = data;
@@ -207,10 +211,10 @@ int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data,
 
        mutex_lock(&perfcnt->lock);
        if (req->enable)
-               ret = panfrost_perfcnt_enable_locked(pfdev, pfile,
+               ret = panfrost_perfcnt_enable_locked(pfdev, file_priv,
                                                     req->counterset);
        else
-               ret = panfrost_perfcnt_disable_locked(pfdev, pfile);
+               ret = panfrost_perfcnt_disable_locked(pfdev, file_priv);
        mutex_unlock(&perfcnt->lock);
 
        return ret;
@@ -248,15 +252,16 @@ out:
        return ret;
 }
 
-void panfrost_perfcnt_close(struct panfrost_file_priv *pfile)
+void panfrost_perfcnt_close(struct drm_file *file_priv)
 {
+       struct panfrost_file_priv *pfile = file_priv->driver_priv;
        struct panfrost_device *pfdev = pfile->pfdev;
        struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
 
        pm_runtime_get_sync(pfdev->dev);
        mutex_lock(&perfcnt->lock);
        if (perfcnt->user == pfile)
-               panfrost_perfcnt_disable_locked(pfdev, pfile);
+               panfrost_perfcnt_disable_locked(pfdev, file_priv);
        mutex_unlock(&perfcnt->lock);
        pm_runtime_mark_last_busy(pfdev->dev);
        pm_runtime_put_autosuspend(pfdev->dev);
index 13b8fda..8bbcf5f 100644 (file)
@@ -9,7 +9,7 @@ void panfrost_perfcnt_sample_done(struct panfrost_device *pfdev);
 void panfrost_perfcnt_clean_cache_done(struct panfrost_device *pfdev);
 int panfrost_perfcnt_init(struct panfrost_device *pfdev);
 void panfrost_perfcnt_fini(struct panfrost_device *pfdev);
-void panfrost_perfcnt_close(struct panfrost_file_priv *pfile);
+void panfrost_perfcnt_close(struct drm_file *file_priv);
 int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data,
                                  struct drm_file *file_priv);
 int panfrost_ioctl_perfcnt_dump(struct drm_device *dev, void *data,
index 7089dfc..110fb38 100644 (file)
@@ -1826,8 +1826,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].use_pitch = 1;
                } else {
                        track->textures[i].use_pitch = 0;
-                       track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
-                       track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+                       track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
+                       track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
                }
                if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
                        track->textures[i].tex_coord_type = 2;
index 8404014..f5f2ffe 100644 (file)
@@ -476,8 +476,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].use_pitch = 1;
                } else {
                        track->textures[i].use_pitch = 0;
-                       track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
-                       track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+                       track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
+                       track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
                }
                if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
                        track->textures[i].lookup_disable = true;
index 5b1f9ff..714af05 100644 (file)
@@ -837,16 +837,15 @@ static int tegra_cursor_atomic_check(struct drm_plane *plane,
 static void tegra_cursor_atomic_update(struct drm_plane *plane,
                                       struct drm_plane_state *old_state)
 {
-       struct tegra_bo *bo = tegra_fb_get_plane(plane->state->fb, 0);
+       struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
        struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
-       struct drm_plane_state *state = plane->state;
        u32 value = CURSOR_CLIP_DISPLAY;
 
        /* rien ne va plus */
        if (!plane->state->crtc || !plane->state->fb)
                return;
 
-       switch (state->crtc_w) {
+       switch (plane->state->crtc_w) {
        case 32:
                value |= CURSOR_SIZE_32x32;
                break;
@@ -864,16 +863,16 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
                break;
 
        default:
-               WARN(1, "cursor size %ux%u not supported\n", state->crtc_w,
-                    state->crtc_h);
+               WARN(1, "cursor size %ux%u not supported\n",
+                    plane->state->crtc_w, plane->state->crtc_h);
                return;
        }
 
-       value |= (bo->iova >> 10) & 0x3fffff;
+       value |= (state->iova[0] >> 10) & 0x3fffff;
        tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR);
 
 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-       value = (bo->iova >> 32) & 0x3;
+       value = (state->iova[0] >> 32) & 0x3;
        tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR_HI);
 #endif
 
@@ -892,7 +891,8 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
        tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL);
 
        /* position the cursor */
-       value = (state->crtc_y & 0x3fff) << 16 | (state->crtc_x & 0x3fff);
+       value = (plane->state->crtc_y & 0x3fff) << 16 |
+               (plane->state->crtc_x & 0x3fff);
        tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
 }
 
@@ -2017,7 +2017,7 @@ static int tegra_dc_init(struct host1x_client *client)
                dev_warn(dc->dev, "failed to allocate syncpoint\n");
 
        err = host1x_client_iommu_attach(client);
-       if (err < 0) {
+       if (err < 0 && err != -ENODEV) {
                dev_err(client->dev, "failed to attach to domain: %d\n", err);
                return err;
        }
index 56e5e7a..f455ce7 100644 (file)
@@ -920,10 +920,8 @@ int host1x_client_iommu_attach(struct host1x_client *client)
 
        if (tegra->domain) {
                group = iommu_group_get(client->dev);
-               if (!group) {
-                       dev_err(client->dev, "failed to get IOMMU group\n");
+               if (!group)
                        return -ENODEV;
-               }
 
                if (domain != tegra->domain) {
                        err = iommu_attach_group(tegra->domain, group);
@@ -1243,6 +1241,9 @@ static int host1x_drm_remove(struct host1x_device *dev)
        drm_atomic_helper_shutdown(drm);
        drm_mode_config_cleanup(drm);
 
+       if (tegra->hub)
+               tegra_display_hub_cleanup(tegra->hub);
+
        err = host1x_device_exit(dev);
        if (err < 0)
                dev_err(&dev->dev, "host1x device cleanup failed: %d\n", err);
index 746dae3..bc15b43 100644 (file)
@@ -27,6 +27,29 @@ static void tegra_bo_put(struct host1x_bo *bo)
        drm_gem_object_put_unlocked(&obj->gem);
 }
 
+/* XXX move this into lib/scatterlist.c? */
+static int sg_alloc_table_from_sg(struct sg_table *sgt, struct scatterlist *sg,
+                                 unsigned int nents, gfp_t gfp_mask)
+{
+       struct scatterlist *dst;
+       unsigned int i;
+       int err;
+
+       err = sg_alloc_table(sgt, nents, gfp_mask);
+       if (err < 0)
+               return err;
+
+       dst = sgt->sgl;
+
+       for (i = 0; i < nents; i++) {
+               sg_set_page(dst, sg_page(sg), sg->length, 0);
+               dst = sg_next(dst);
+               sg = sg_next(sg);
+       }
+
+       return 0;
+}
+
 static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
                                     dma_addr_t *phys)
 {
@@ -52,11 +75,31 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
                return ERR_PTR(-ENOMEM);
 
        if (obj->pages) {
+               /*
+                * If the buffer object was allocated from the explicit IOMMU
+                * API code paths, construct an SG table from the pages.
+                */
                err = sg_alloc_table_from_pages(sgt, obj->pages, obj->num_pages,
                                                0, obj->gem.size, GFP_KERNEL);
                if (err < 0)
                        goto free;
+       } else if (obj->sgt) {
+               /*
+                * If the buffer object already has an SG table but no pages
+                * were allocated for it, it means the buffer was imported and
+                * the SG table needs to be copied to avoid overwriting any
+                * other potential users of the original SG table.
+                */
+               err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
+                                            GFP_KERNEL);
+               if (err < 0)
+                       goto free;
        } else {
+               /*
+                * If the buffer object had no pages allocated and if it was
+                * not imported, it had to be allocated with the DMA API, so
+                * the DMA API helper can be used.
+                */
                err = dma_get_sgtable(dev, sgt, obj->vaddr, obj->iova,
                                      obj->gem.size);
                if (err < 0)
@@ -397,13 +440,6 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
                err = tegra_bo_iommu_map(tegra, bo);
                if (err < 0)
                        goto detach;
-       } else {
-               if (bo->sgt->nents > 1) {
-                       err = -EINVAL;
-                       goto detach;
-               }
-
-               bo->iova = sg_dma_address(bo->sgt->sgl);
        }
 
        bo->gem.import_attach = attach;
index 2b4082d..47d985a 100644 (file)
@@ -605,11 +605,8 @@ static struct tegra_display_hub_state *
 tegra_display_hub_get_state(struct tegra_display_hub *hub,
                            struct drm_atomic_state *state)
 {
-       struct drm_device *drm = dev_get_drvdata(hub->client.parent);
        struct drm_private_state *priv;
 
-       WARN_ON(!drm_modeset_is_locked(&drm->mode_config.connection_mutex));
-
        priv = drm_atomic_get_private_obj_state(state, &hub->base);
        if (IS_ERR(priv))
                return ERR_CAST(priv);
index 163b590..cadcdd9 100644 (file)
@@ -129,6 +129,17 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
                                goto unpin;
                        }
 
+                       /*
+                        * The display controller needs contiguous memory, so
+                        * fail if the buffer is discontiguous and we fail to
+                        * map its SG table to a single contiguous chunk of
+                        * I/O virtual memory.
+                        */
+                       if (err > 1) {
+                               err = -EINVAL;
+                               goto unpin;
+                       }
+
                        state->iova[i] = sg_dma_address(sgt->sgl);
                        state->sgt[i] = sgt;
                } else {
index 615cb31..a68d3b3 100644 (file)
@@ -3912,8 +3912,7 @@ static int tegra_sor_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int tegra_sor_suspend(struct device *dev)
+static int tegra_sor_runtime_suspend(struct device *dev)
 {
        struct tegra_sor *sor = dev_get_drvdata(dev);
        int err;
@@ -3935,7 +3934,7 @@ static int tegra_sor_suspend(struct device *dev)
        return 0;
 }
 
-static int tegra_sor_resume(struct device *dev)
+static int tegra_sor_runtime_resume(struct device *dev)
 {
        struct tegra_sor *sor = dev_get_drvdata(dev);
        int err;
@@ -3967,10 +3966,39 @@ static int tegra_sor_resume(struct device *dev)
 
        return 0;
 }
-#endif
+
+static int tegra_sor_suspend(struct device *dev)
+{
+       struct tegra_sor *sor = dev_get_drvdata(dev);
+       int err;
+
+       if (sor->hdmi_supply) {
+               err = regulator_disable(sor->hdmi_supply);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int tegra_sor_resume(struct device *dev)
+{
+       struct tegra_sor *sor = dev_get_drvdata(dev);
+       int err;
+
+       if (sor->hdmi_supply) {
+               err = regulator_enable(sor->hdmi_supply);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
 
 static const struct dev_pm_ops tegra_sor_pm_ops = {
-       SET_RUNTIME_PM_OPS(tegra_sor_suspend, tegra_sor_resume, NULL)
+       SET_RUNTIME_PM_OPS(tegra_sor_runtime_suspend, tegra_sor_runtime_resume,
+                          NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume)
 };
 
 struct platform_driver tegra_sor_driver = {
index 9444ba1..3526c28 100644 (file)
@@ -167,7 +167,7 @@ static int vic_init(struct host1x_client *client)
        int err;
 
        err = host1x_client_iommu_attach(client);
-       if (err < 0) {
+       if (err < 0 && err != -ENODEV) {
                dev_err(vic->dev, "failed to attach to domain: %d\n", err);
                return err;
        }
@@ -386,13 +386,14 @@ static const struct vic_config vic_t194_config = {
        .supports_sid = true,
 };
 
-static const struct of_device_id vic_match[] = {
+static const struct of_device_id tegra_vic_of_match[] = {
        { .compatible = "nvidia,tegra124-vic", .data = &vic_t124_config },
        { .compatible = "nvidia,tegra210-vic", .data = &vic_t210_config },
        { .compatible = "nvidia,tegra186-vic", .data = &vic_t186_config },
        { .compatible = "nvidia,tegra194-vic", .data = &vic_t194_config },
        { },
 };
+MODULE_DEVICE_TABLE(of, tegra_vic_of_match);
 
 static int vic_probe(struct platform_device *pdev)
 {
@@ -516,7 +517,7 @@ static const struct dev_pm_ops vic_pm_ops = {
 struct platform_driver tegra_vic_driver = {
        .driver = {
                .name = "tegra-vic",
-               .of_match_table = vic_match,
+               .of_match_table = tegra_vic_of_match,
                .pm = &vic_pm_ops
        },
        .probe = vic_probe,
index 9333c86..9f8dcd3 100644 (file)
@@ -896,29 +896,6 @@ struct i2c_client *i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address
 }
 EXPORT_SYMBOL_GPL(i2c_new_dummy_device);
 
-/**
- * i2c_new_dummy - return a new i2c device bound to a dummy driver
- * @adapter: the adapter managing the device
- * @address: seven bit address to be used
- * Context: can sleep
- *
- * This deprecated function has the same functionality as @i2c_new_dummy_device,
- * it just returns NULL instead of an ERR_PTR in case of an error for
- * compatibility with current I2C API. It will be removed once all users are
- * converted.
- *
- * This returns the new i2c client, which should be saved for later use with
- * i2c_unregister_device(); or NULL to indicate an error.
- */
-struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
-{
-       struct i2c_client *ret;
-
-       ret = i2c_new_dummy_device(adapter, address);
-       return IS_ERR(ret) ? NULL : ret;
-}
-EXPORT_SYMBOL_GPL(i2c_new_dummy);
-
 struct i2c_dummy_devres {
        struct i2c_client *client;
 };
index 347b08b..75fd2a7 100644 (file)
@@ -1291,8 +1291,8 @@ static void sklh_idle_state_table_update(void)
                        return;
        }
 
-       skl_cstates[5].disabled = 1;    /* C8-SKL */
-       skl_cstates[6].disabled = 1;    /* C9-SKL */
+       skl_cstates[5].flags |= CPUIDLE_FLAG_UNUSABLE;  /* C8-SKL */
+       skl_cstates[6].flags |= CPUIDLE_FLAG_UNUSABLE;  /* C9-SKL */
 }
 /*
  * intel_idle_state_table_update()
@@ -1355,7 +1355,7 @@ static void __init intel_idle_cpuidle_driver_init(void)
                        continue;
 
                /* if state marked as disabled, skip it */
-               if (cpuidle_state_table[cstate].disabled != 0) {
+               if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) {
                        pr_debug("state %s is disabled\n",
                                 cpuidle_state_table[cstate].name);
                        continue;
index 7b83764..7320275 100644 (file)
@@ -992,6 +992,7 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
 #define ST_ACCEL_TRIGGER_OPS NULL
 #endif
 
+#ifdef CONFIG_ACPI
 static const struct iio_mount_matrix *
 get_mount_matrix(const struct iio_dev *indio_dev,
                 const struct iio_chan_spec *chan)
@@ -1012,7 +1013,6 @@ static const struct iio_chan_spec_ext_info mount_matrix_ext_info[] = {
 static int apply_acpi_orientation(struct iio_dev *indio_dev,
                                  struct iio_chan_spec *channels)
 {
-#ifdef CONFIG_ACPI
        struct st_sensor_data *adata = iio_priv(indio_dev);
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
        struct acpi_device *adev;
@@ -1140,10 +1140,14 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev,
 out:
        kfree(buffer.pointer);
        return ret;
+}
 #else /* !CONFIG_ACPI */
+static int apply_acpi_orientation(struct iio_dev *indio_dev,
+                                 struct iio_chan_spec *channels)
+{
        return 0;
-#endif
 }
+#endif
 
 /*
  * st_accel_get_settings() - get sensor settings from device name
index edc6f1c..3f03abf 100644 (file)
@@ -39,6 +39,8 @@
 #define AD7124_STATUS_POR_FLAG_MSK     BIT(4)
 
 /* AD7124_ADC_CONTROL */
+#define AD7124_ADC_CTRL_REF_EN_MSK     BIT(8)
+#define AD7124_ADC_CTRL_REF_EN(x)      FIELD_PREP(AD7124_ADC_CTRL_REF_EN_MSK, x)
 #define AD7124_ADC_CTRL_PWR_MSK        GENMASK(7, 6)
 #define AD7124_ADC_CTRL_PWR(x)         FIELD_PREP(AD7124_ADC_CTRL_PWR_MSK, x)
 #define AD7124_ADC_CTRL_MODE_MSK       GENMASK(5, 2)
@@ -424,7 +426,10 @@ static int ad7124_init_channel_vref(struct ad7124_state *st,
                break;
        case AD7124_INT_REF:
                st->channel_config[channel_number].vref_mv = 2500;
-               break;
+               st->adc_control &= ~AD7124_ADC_CTRL_REF_EN_MSK;
+               st->adc_control |= AD7124_ADC_CTRL_REF_EN(1);
+               return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL,
+                                     2, st->adc_control);
        default:
                dev_err(&st->sd.spi->dev, "Invalid reference %d\n", refsel);
                return -EINVAL;
index f5ba94c..e4683a6 100644 (file)
@@ -85,7 +85,7 @@ err_unlock:
 
 static int ad7606_read_samples(struct ad7606_state *st)
 {
-       unsigned int num = st->chip_info->num_channels;
+       unsigned int num = st->chip_info->num_channels - 1;
        u16 *data = st->data;
        int ret;
 
index 5c2b344..2c6f60e 100644 (file)
@@ -89,6 +89,7 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val,
                                   unsigned int channel)
 {
        int ret;
+       int i;
        int bits_per_word = ad7949_adc->resolution;
        int mask = GENMASK(ad7949_adc->resolution, 0);
        struct spi_message msg;
@@ -100,12 +101,23 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val,
                },
        };
 
-       ret = ad7949_spi_write_cfg(ad7949_adc,
-                                  channel << AD7949_OFFSET_CHANNEL_SEL,
-                                  AD7949_MASK_CHANNEL_SEL);
-       if (ret)
-               return ret;
+       /*
+        * 1: write CFG for sample N and read old data (sample N-2)
+        * 2: if CFG was not changed since sample N-1 then we'll get good data
+        *    at the next xfer, so we bail out now, otherwise we write something
+        *    and we read garbage (sample N-1 configuration).
+        */
+       for (i = 0; i < 2; i++) {
+               ret = ad7949_spi_write_cfg(ad7949_adc,
+                                          channel << AD7949_OFFSET_CHANNEL_SEL,
+                                          AD7949_MASK_CHANNEL_SEL);
+               if (ret)
+                       return ret;
+               if (channel == ad7949_adc->current_channel)
+                       break;
+       }
 
+       /* 3: write something and read actual data */
        ad7949_adc->buffer = 0;
        spi_message_init_with_transfers(&msg, tx, 1);
        ret = spi_sync(ad7949_adc->spi, &msg);
index 67d096f..c35a1be 100644 (file)
@@ -185,7 +185,7 @@ static int mrfld_adc_probe(struct platform_device *pdev)
        int irq;
        int ret;
 
-       indio_dev = devm_iio_device_alloc(dev, sizeof(*indio_dev));
+       indio_dev = devm_iio_device_alloc(dev, sizeof(struct mrfld_adc));
        if (!indio_dev)
                return -ENOMEM;
 
index e171db2..02834ca 100644 (file)
@@ -478,7 +478,13 @@ static int max1027_probe(struct spi_device *spi)
                st->trig->ops = &max1027_trigger_ops;
                st->trig->dev.parent = &spi->dev;
                iio_trigger_set_drvdata(st->trig, indio_dev);
-               iio_trigger_register(st->trig);
+               ret = devm_iio_trigger_register(&indio_dev->dev,
+                                               st->trig);
+               if (ret < 0) {
+                       dev_err(&indio_dev->dev,
+                               "Failed to register iio trigger\n");
+                       return ret;
+               }
 
                ret = devm_request_threaded_irq(&spi->dev, spi->irq,
                                                iio_trigger_generic_data_rdy_poll,
index da073d7..e480529 100644 (file)
 #define MAX9611_TEMP_SCALE_NUM         1000000
 #define MAX9611_TEMP_SCALE_DIV         2083
 
+/*
+ * Conversion time is 2 ms (typically) at Ta=25 degreeC
+ * No maximum value is known, so play it safe.
+ */
+#define MAX9611_CONV_TIME_US_RANGE     3000, 3300
+
 struct max9611_dev {
        struct device *dev;
        struct i2c_client *i2c_client;
@@ -236,11 +242,9 @@ static int max9611_read_single(struct max9611_dev *max9611,
                return ret;
        }
 
-       /*
-        * need a delay here to make register configuration
-        * stabilize. 1 msec at least, from empirical testing.
-        */
-       usleep_range(1000, 2000);
+       /* need a delay here to make register configuration stabilize. */
+
+       usleep_range(MAX9611_CONV_TIME_US_RANGE);
 
        ret = i2c_smbus_read_word_swapped(max9611->i2c_client, reg_addr);
        if (ret < 0) {
@@ -507,7 +511,7 @@ static int max9611_init(struct max9611_dev *max9611)
                        MAX9611_REG_CTRL2, 0);
                return ret;
        }
-       usleep_range(1000, 2000);
+       usleep_range(MAX9611_CONV_TIME_US_RANGE);
 
        return 0;
 }
index 963ff04..7ecd2ff 100644 (file)
@@ -229,7 +229,7 @@ static int hdc100x_read_raw(struct iio_dev *indio_dev,
                        *val2 = 65536;
                        return IIO_VAL_FRACTIONAL;
                } else {
-                       *val = 100;
+                       *val = 100000;
                        *val2 = 65536;
                        return IIO_VAL_FRACTIONAL;
                }
index 45e77b3..0686e41 100644 (file)
@@ -117,6 +117,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6050,
                .config = &chip_config_6050,
                .fifo_size = 1024,
+               .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU6500_WHOAMI_VALUE,
@@ -124,6 +125,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU6515_WHOAMI_VALUE,
@@ -131,6 +133,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU6000_WHOAMI_VALUE,
@@ -138,6 +141,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6050,
                .config = &chip_config_6050,
                .fifo_size = 1024,
+               .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU9150_WHOAMI_VALUE,
@@ -145,6 +149,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6050,
                .config = &chip_config_6050,
                .fifo_size = 1024,
+               .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU9250_WHOAMI_VALUE,
@@ -152,6 +157,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_MPU9255_WHOAMI_VALUE,
@@ -159,6 +165,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
        },
        {
                .whoami = INV_ICM20608_WHOAMI_VALUE,
@@ -166,6 +173,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_6500,
                .config = &chip_config_6050,
                .fifo_size = 512,
+               .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
        },
        {
                .whoami = INV_ICM20602_WHOAMI_VALUE,
@@ -173,6 +181,7 @@ static const struct inv_mpu6050_hw hw_info[] = {
                .reg = &reg_set_icm20602,
                .config = &chip_config_6050,
                .fifo_size = 1008,
+               .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
        },
 };
 
@@ -481,12 +490,8 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev,
 
                        return IIO_VAL_INT_PLUS_MICRO;
                case IIO_TEMP:
-                       *val = 0;
-                       if (st->chip_type == INV_ICM20602)
-                               *val2 = INV_ICM20602_TEMP_SCALE;
-                       else
-                               *val2 = INV_MPU6050_TEMP_SCALE;
-
+                       *val = st->hw->temp.scale / 1000000;
+                       *val2 = st->hw->temp.scale % 1000000;
                        return IIO_VAL_INT_PLUS_MICRO;
                case IIO_MAGN:
                        return inv_mpu_magn_get_scale(st, chan, val, val2);
@@ -496,11 +501,7 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev,
        case IIO_CHAN_INFO_OFFSET:
                switch (chan->type) {
                case IIO_TEMP:
-                       if (st->chip_type == INV_ICM20602)
-                               *val = INV_ICM20602_TEMP_OFFSET;
-                       else
-                               *val = INV_MPU6050_TEMP_OFFSET;
-
+                       *val = st->hw->temp.offset;
                        return IIO_VAL_INT;
                default:
                        return -EINVAL;
index f1fb7b6..b096e01 100644 (file)
@@ -107,6 +107,7 @@ struct inv_mpu6050_chip_config {
  *  @reg:   register map of the chip.
  *  @config:    configuration of the chip.
  *  @fifo_size:        size of the FIFO in bytes.
+ *  @temp:     offset and scale to apply to raw temperature.
  */
 struct inv_mpu6050_hw {
        u8 whoami;
@@ -114,6 +115,10 @@ struct inv_mpu6050_hw {
        const struct inv_mpu6050_reg_map *reg;
        const struct inv_mpu6050_chip_config *config;
        size_t fifo_size;
+       struct {
+               int offset;
+               int scale;
+       } temp;
 };
 
 /*
@@ -279,16 +284,19 @@ struct inv_mpu6050_state {
 #define INV_MPU6050_REG_UP_TIME_MIN          5000
 #define INV_MPU6050_REG_UP_TIME_MAX          10000
 
-#define INV_MPU6050_TEMP_OFFSET                     12421
-#define INV_MPU6050_TEMP_SCALE               2941
+#define INV_MPU6050_TEMP_OFFSET                     12420
+#define INV_MPU6050_TEMP_SCALE               2941176
 #define INV_MPU6050_MAX_GYRO_FS_PARAM        3
 #define INV_MPU6050_MAX_ACCL_FS_PARAM        3
 #define INV_MPU6050_THREE_AXIS               3
 #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT    3
 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT    3
 
-#define INV_ICM20602_TEMP_OFFSET            8170
-#define INV_ICM20602_TEMP_SCALE                     3060
+#define INV_MPU6500_TEMP_OFFSET              7011
+#define INV_MPU6500_TEMP_SCALE               2995178
+
+#define INV_ICM20608_TEMP_OFFSET            8170
+#define INV_ICM20608_TEMP_SCALE                     3059976
 
 /* 6 + 6 + 7 (for MPU9x50) = 19 round up to 24 and plus 8 */
 #define INV_MPU6050_OUTPUT_DATA_SIZE         32
index c605b15..dc55d7d 100644 (file)
@@ -320,7 +320,6 @@ enum st_lsm6dsx_fifo_mode {
  * @odr: Output data rate of the sensor [Hz].
  * @watermark: Sensor watermark level.
  * @sip: Number of samples in a given pattern.
- * @decimator: FIFO decimation factor.
  * @ts_ref: Sensor timestamp reference for hw one.
  * @ext_info: Sensor settings if it is connected to i2c controller
  */
@@ -334,7 +333,6 @@ struct st_lsm6dsx_sensor {
 
        u16 watermark;
        u8 sip;
-       u8 decimator;
        s64 ts_ref;
 
        struct {
@@ -351,9 +349,9 @@ struct st_lsm6dsx_sensor {
  * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
  * @conf_lock: Mutex to prevent concurrent FIFO configuration update.
  * @page_lock: Mutex to prevent concurrent memory page configuration.
- * @fifo_mode: FIFO operating mode supported by the device.
  * @suspend_mask: Suspended sensor bitmask.
  * @enable_mask: Enabled sensor bitmask.
+ * @fifo_mask: Enabled hw FIFO bitmask.
  * @ts_gain: Hw timestamp rate after internal calibration.
  * @ts_sip: Total number of timestamp samples in a given pattern.
  * @sip: Total number of samples (acc/gyro/ts) in a given pattern.
@@ -373,9 +371,9 @@ struct st_lsm6dsx_hw {
        struct mutex conf_lock;
        struct mutex page_lock;
 
-       enum st_lsm6dsx_fifo_mode fifo_mode;
        u8 suspend_mask;
        u8 enable_mask;
+       u8 fifo_mask;
        s64 ts_gain;
        u8 ts_sip;
        u8 sip;
index d416990..cb536b8 100644 (file)
@@ -78,14 +78,20 @@ struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
        { 32, 0x7 },
 };
 
-static int st_lsm6dsx_get_decimator_val(u8 val)
+static int
+st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr)
 {
        const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table);
+       u32 decimator =  max_odr / sensor->odr;
        int i;
 
-       for (i = 0; i < max_size; i++)
-               if (st_lsm6dsx_decimator_table[i].decimator == val)
+       if (decimator > 1)
+               decimator = round_down(decimator, 2);
+
+       for (i = 0; i < max_size; i++) {
+               if (st_lsm6dsx_decimator_table[i].decimator == decimator)
                        break;
+       }
 
        return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
 }
@@ -111,6 +117,13 @@ static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
        }
 }
 
+static u8 st_lsm6dsx_get_sip(struct st_lsm6dsx_sensor *sensor, u32 min_odr)
+{
+       u8 sip = sensor->odr / min_odr;
+
+       return sip > 1 ? round_down(sip, 2) : sip;
+}
+
 static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
 {
        const struct st_lsm6dsx_reg *ts_dec_reg;
@@ -131,12 +144,10 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
                sensor = iio_priv(hw->iio_devs[i]);
                /* update fifo decimators and sample in pattern */
                if (hw->enable_mask & BIT(sensor->id)) {
-                       sensor->sip = sensor->odr / min_odr;
-                       sensor->decimator = max_odr / sensor->odr;
-                       data = st_lsm6dsx_get_decimator_val(sensor->decimator);
+                       sensor->sip = st_lsm6dsx_get_sip(sensor, min_odr);
+                       data = st_lsm6dsx_get_decimator_val(sensor, max_odr);
                } else {
                        sensor->sip = 0;
-                       sensor->decimator = 0;
                        data = 0;
                }
                ts_sip = max_t(u16, ts_sip, sensor->sip);
@@ -176,17 +187,10 @@ int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
                             enum st_lsm6dsx_fifo_mode fifo_mode)
 {
        unsigned int data;
-       int err;
 
        data = FIELD_PREP(ST_LSM6DSX_FIFO_MODE_MASK, fifo_mode);
-       err = st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
-                                           ST_LSM6DSX_FIFO_MODE_MASK, data);
-       if (err < 0)
-               return err;
-
-       hw->fifo_mode = fifo_mode;
-
-       return 0;
+       return st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
+                                            ST_LSM6DSX_FIFO_MODE_MASK, data);
 }
 
 static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
@@ -608,11 +612,17 @@ int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
 int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
 {
        struct st_lsm6dsx_hw *hw = sensor->hw;
+       u8 fifo_mask;
        int err;
 
        mutex_lock(&hw->conf_lock);
 
-       if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) {
+       if (enable)
+               fifo_mask = hw->fifo_mask | BIT(sensor->id);
+       else
+               fifo_mask = hw->fifo_mask & ~BIT(sensor->id);
+
+       if (hw->fifo_mask) {
                err = st_lsm6dsx_flush_fifo(hw);
                if (err < 0)
                        goto out;
@@ -642,15 +652,19 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
        if (err < 0)
                goto out;
 
-       if (hw->enable_mask) {
+       if (fifo_mask) {
                /* reset hw ts counter */
                err = st_lsm6dsx_reset_hw_ts(hw);
                if (err < 0)
                        goto out;
 
                err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
+               if (err < 0)
+                       goto out;
        }
 
+       hw->fifo_mask = fifo_mask;
+
 out:
        mutex_unlock(&hw->conf_lock);
 
index 11b2c7b..a7d40c0 100644 (file)
@@ -1447,8 +1447,9 @@ st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr)
        return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
 }
 
-int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
-                                bool enable)
+static int
+__st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
+                              bool enable)
 {
        struct st_lsm6dsx_hw *hw = sensor->hw;
        u32 odr = enable ? sensor->odr : 0;
@@ -1466,6 +1467,26 @@ int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
        return 0;
 }
 
+static int
+st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable)
+{
+       struct st_lsm6dsx_hw *hw = sensor->hw;
+
+       if (sensor->id == ST_LSM6DSX_ID_GYRO || enable)
+               return 0;
+
+       return hw->enable_event;
+}
+
+int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
+                                bool enable)
+{
+       if (st_lsm6dsx_check_events(sensor, enable))
+               return 0;
+
+       return __st_lsm6dsx_sensor_set_enable(sensor, enable);
+}
+
 static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
                                   u8 addr, int *val)
 {
@@ -1661,7 +1682,7 @@ st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
        struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
        struct st_lsm6dsx_hw *hw = sensor->hw;
        u8 enable_event;
-       int err = 0;
+       int err;
 
        if (type != IIO_EV_TYPE_THRESH)
                return -EINVAL;
@@ -1689,7 +1710,8 @@ st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
                return err;
 
        mutex_lock(&hw->conf_lock);
-       err = st_lsm6dsx_sensor_set_enable(sensor, state);
+       if (enable_event || !(hw->fifo_mask & BIT(sensor->id)))
+               err = __st_lsm6dsx_sensor_set_enable(sensor, state);
        mutex_unlock(&hw->conf_lock);
        if (err < 0)
                return err;
@@ -2300,7 +2322,7 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
                hw->suspend_mask |= BIT(sensor->id);
        }
 
-       if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
+       if (hw->fifo_mask)
                err = st_lsm6dsx_flush_fifo(hw);
 
        return err;
@@ -2336,7 +2358,7 @@ static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
                hw->suspend_mask &= ~BIT(sensor->id);
        }
 
-       if (hw->enable_mask)
+       if (hw->fifo_mask)
                err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
 
        return err;
index ddf4702..d39c0d6 100644 (file)
@@ -444,8 +444,10 @@ static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new(
                        else
                                temp = __convert_to_raw(temp, resolution);
                } else {
-                       of_property_read_u32_index(np, propname, index,
-                                                  (u32 *)&temp);
+                       u32 t32;
+
+                       of_property_read_u32_index(np, propname, index, &t32);
+                       temp = t32;
                }
 
                for (j = 0; j < n_size; j++)
index 6d7ec37..606fa6d 100644 (file)
@@ -421,16 +421,15 @@ static int addr6_resolve(struct sockaddr *src_sock,
                                (const struct sockaddr_in6 *)dst_sock;
        struct flowi6 fl6;
        struct dst_entry *dst;
-       int ret;
 
        memset(&fl6, 0, sizeof fl6);
        fl6.daddr = dst_in->sin6_addr;
        fl6.saddr = src_in->sin6_addr;
        fl6.flowi6_oif = addr->bound_dev_if;
 
-       ret = ipv6_stub->ipv6_dst_lookup(addr->net, NULL, &dst, &fl6);
-       if (ret < 0)
-               return ret;
+       dst = ipv6_stub->ipv6_dst_lookup_flow(addr->net, NULL, &fl6, NULL);
+       if (IS_ERR(dst))
+               return PTR_ERR(dst);
 
        if (ipv6_addr_any(&src_in->sin6_addr))
                src_in->sin6_addr = fl6.saddr;
index 25f2b70..43a6f07 100644 (file)
@@ -4763,6 +4763,7 @@ err_ib:
 err:
        unregister_netdevice_notifier(&cma_nb);
        ib_sa_unregister_client(&sa_client);
+       unregister_pernet_subsys(&cma_pernet_operations);
 err_wq:
        destroy_workqueue(cma_wq);
        return ret;
index 8434ec0..2257d7f 100644 (file)
@@ -286,6 +286,9 @@ int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port)
        struct rdma_counter *counter;
        int ret;
 
+       if (!qp->res.valid)
+               return 0;
+
        if (!rdma_is_port_valid(dev, port))
                return -EINVAL;
 
index f509c47..b7cb598 100644 (file)
@@ -238,28 +238,32 @@ void rdma_user_mmap_entry_remove(struct rdma_user_mmap_entry *entry)
 EXPORT_SYMBOL(rdma_user_mmap_entry_remove);
 
 /**
- * rdma_user_mmap_entry_insert() - Insert an entry to the mmap_xa
+ * rdma_user_mmap_entry_insert_range() - Insert an entry to the mmap_xa
+ *                                      in a given range.
  *
  * @ucontext: associated user context.
  * @entry: the entry to insert into the mmap_xa
  * @length: length of the address that will be mmapped
+ * @min_pgoff: minimum pgoff to be returned
+ * @max_pgoff: maximum pgoff to be returned
  *
  * This function should be called by drivers that use the rdma_user_mmap
  * interface for implementing their mmap syscall A database of mmap offsets is
  * handled in the core and helper functions are provided to insert entries
  * into the database and extract entries when the user calls mmap with the
- * given offset.  The function allocates a unique page offset that should be
- * provided to user, the user will use the offset to retrieve information such
- * as address to be mapped and how.
+ * given offset. The function allocates a unique page offset in a given range
+ * that should be provided to user, the user will use the offset to retrieve
+ * information such as address to be mapped and how.
  *
  * Return: 0 on success and -ENOMEM on failure
  */
-int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
-                               struct rdma_user_mmap_entry *entry,
-                               size_t length)
+int rdma_user_mmap_entry_insert_range(struct ib_ucontext *ucontext,
+                                     struct rdma_user_mmap_entry *entry,
+                                     size_t length, u32 min_pgoff,
+                                     u32 max_pgoff)
 {
        struct ib_uverbs_file *ufile = ucontext->ufile;
-       XA_STATE(xas, &ucontext->mmap_xa, 0);
+       XA_STATE(xas, &ucontext->mmap_xa, min_pgoff);
        u32 xa_first, xa_last, npages;
        int err;
        u32 i;
@@ -285,7 +289,7 @@ int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
        entry->npages = npages;
        while (true) {
                /* First find an empty index */
-               xas_find_marked(&xas, U32_MAX, XA_FREE_MARK);
+               xas_find_marked(&xas, max_pgoff, XA_FREE_MARK);
                if (xas.xa_node == XAS_RESTART)
                        goto err_unlock;
 
@@ -332,4 +336,30 @@ err_unlock:
        mutex_unlock(&ufile->umap_lock);
        return -ENOMEM;
 }
+EXPORT_SYMBOL(rdma_user_mmap_entry_insert_range);
+
+/**
+ * rdma_user_mmap_entry_insert() - Insert an entry to the mmap_xa.
+ *
+ * @ucontext: associated user context.
+ * @entry: the entry to insert into the mmap_xa
+ * @length: length of the address that will be mmapped
+ *
+ * This function should be called by drivers that use the rdma_user_mmap
+ * interface for handling user mmapped addresses. The database is handled in
+ * the core and helper functions are provided to insert entries into the
+ * database and extract entries when the user calls mmap with the given offset.
+ * The function allocates a unique page offset that should be provided to user,
+ * the user will use the offset to retrieve information such as address to
+ * be mapped and how.
+ *
+ * Return: 0 on success and -ENOMEM on failure
+ */
+int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
+                               struct rdma_user_mmap_entry *entry,
+                               size_t length)
+{
+       return rdma_user_mmap_entry_insert_range(ucontext, entry, length, 0,
+                                                U32_MAX);
+}
 EXPORT_SYMBOL(rdma_user_mmap_entry_insert);
index c9d294c..50c2257 100644 (file)
@@ -145,7 +145,7 @@ static inline bool is_rdma_read_cap(struct efa_dev *dev)
 }
 
 #define field_avail(x, fld, sz) (offsetof(typeof(x), fld) + \
-                                FIELD_SIZEOF(typeof(x), fld) <= (sz))
+                                sizeof_field(typeof(x), fld) <= (sz))
 
 #define is_reserved_cleared(reserved) \
        !memchr_inv(reserved, 0, sizeof(reserved))
index 5774dfc..a515256 100644 (file)
@@ -848,7 +848,7 @@ static const struct rhashtable_params sdma_rht_params = {
        .nelem_hint = NR_CPUS_HINT,
        .head_offset = offsetof(struct sdma_rht_node, node),
        .key_offset = offsetof(struct sdma_rht_node, cpu_id),
-       .key_len = FIELD_SIZEOF(struct sdma_rht_node, cpu_id),
+       .key_len = sizeof_field(struct sdma_rht_node, cpu_id),
        .max_size = NR_CPUS,
        .min_size = 8,
        .automatic_shrinking = true,
index b0e9bf7..d36e3e1 100644 (file)
@@ -107,9 +107,9 @@ enum {
        HFI1_HAS_GRH = (1 << 0),
 };
 
-#define LRH_16B_BYTES (FIELD_SIZEOF(struct hfi1_16b_header, lrh))
+#define LRH_16B_BYTES (sizeof_field(struct hfi1_16b_header, lrh))
 #define LRH_16B_DWORDS (LRH_16B_BYTES / sizeof(u32))
-#define LRH_9B_BYTES (FIELD_SIZEOF(struct ib_header, lrh))
+#define LRH_9B_BYTES (sizeof_field(struct ib_header, lrh))
 #define LRH_9B_DWORDS (LRH_9B_BYTES / sizeof(u32))
 
 /* 24Bits for qpn, upper 8Bits reserved */
index 0b5dc1d..34055cb 100644 (file)
@@ -3018,16 +3018,17 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
        ibdev->ib_active = false;
        flush_workqueue(wq);
 
-       mlx4_ib_close_sriov(ibdev);
-       mlx4_ib_mad_cleanup(ibdev);
-       ib_unregister_device(&ibdev->ib_dev);
-       mlx4_ib_diag_cleanup(ibdev);
        if (ibdev->iboe.nb.notifier_call) {
                if (unregister_netdevice_notifier(&ibdev->iboe.nb))
                        pr_warn("failure unregistering notifier\n");
                ibdev->iboe.nb.notifier_call = NULL;
        }
 
+       mlx4_ib_close_sriov(ibdev);
+       mlx4_ib_mad_cleanup(ibdev);
+       ib_unregister_device(&ibdev->ib_dev);
+       mlx4_ib_diag_cleanup(ibdev);
+
        mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
                              ibdev->steer_qpn_count);
        kfree(ibdev->ib_uc_qpns_bitmap);
index 4937947..4c26492 100644 (file)
@@ -157,7 +157,7 @@ int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
        return -ENOMEM;
 }
 
-int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length)
+void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length)
 {
        struct mlx5_core_dev *dev = dm->dev;
        u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr);
@@ -175,15 +175,13 @@ int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length)
        MLX5_SET(dealloc_memic_in, in, memic_size, length);
 
        err =  mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+       if (err)
+               return;
 
-       if (!err) {
-               spin_lock(&dm->lock);
-               bitmap_clear(dm->memic_alloc_pages,
-                            start_page_idx, num_pages);
-               spin_unlock(&dm->lock);
-       }
-
-       return err;
+       spin_lock(&dm->lock);
+       bitmap_clear(dm->memic_alloc_pages,
+                    start_page_idx, num_pages);
+       spin_unlock(&dm->lock);
 }
 
 int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out)
index 169cab4..945ebce 100644 (file)
@@ -46,7 +46,7 @@ int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev,
                                void *in, int in_size);
 int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
                         u64 length, u32 alignment);
-int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length);
+void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length);
 void mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid);
 void mlx5_cmd_destroy_tir(struct mlx5_core_dev *dev, u32 tirn, u16 uid);
 void mlx5_cmd_destroy_tis(struct mlx5_core_dev *dev, u32 tisn, u16 uid);
index 5110035..997cbfe 100644 (file)
@@ -2074,6 +2074,24 @@ static int mlx5_ib_mmap_clock_info_page(struct mlx5_ib_dev *dev,
                              virt_to_page(dev->mdev->clock_info));
 }
 
+static void mlx5_ib_mmap_free(struct rdma_user_mmap_entry *entry)
+{
+       struct mlx5_user_mmap_entry *mentry = to_mmmap(entry);
+       struct mlx5_ib_dev *dev = to_mdev(entry->ucontext->device);
+       struct mlx5_ib_dm *mdm;
+
+       switch (mentry->mmap_flag) {
+       case MLX5_IB_MMAP_TYPE_MEMIC:
+               mdm = container_of(mentry, struct mlx5_ib_dm, mentry);
+               mlx5_cmd_dealloc_memic(&dev->dm, mdm->dev_addr,
+                                      mdm->size);
+               kfree(mdm);
+               break;
+       default:
+               WARN_ON(true);
+       }
+}
+
 static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
                    struct vm_area_struct *vma,
                    struct mlx5_ib_ucontext *context)
@@ -2186,26 +2204,55 @@ free_bfreg:
        return err;
 }
 
-static int dm_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
+static int add_dm_mmap_entry(struct ib_ucontext *context,
+                            struct mlx5_ib_dm *mdm,
+                            u64 address)
+{
+       mdm->mentry.mmap_flag = MLX5_IB_MMAP_TYPE_MEMIC;
+       mdm->mentry.address = address;
+       return rdma_user_mmap_entry_insert_range(
+                       context, &mdm->mentry.rdma_entry,
+                       mdm->size,
+                       MLX5_IB_MMAP_DEVICE_MEM << 16,
+                       (MLX5_IB_MMAP_DEVICE_MEM << 16) + (1UL << 16) - 1);
+}
+
+static unsigned long mlx5_vma_to_pgoff(struct vm_area_struct *vma)
+{
+       unsigned long idx;
+       u8 command;
+
+       command = get_command(vma->vm_pgoff);
+       idx = get_extended_index(vma->vm_pgoff);
+
+       return (command << 16 | idx);
+}
+
+static int mlx5_ib_mmap_offset(struct mlx5_ib_dev *dev,
+                              struct vm_area_struct *vma,
+                              struct ib_ucontext *ucontext)
 {
-       struct mlx5_ib_ucontext *mctx = to_mucontext(context);
-       struct mlx5_ib_dev *dev = to_mdev(context->device);
-       u16 page_idx = get_extended_index(vma->vm_pgoff);
-       size_t map_size = vma->vm_end - vma->vm_start;
-       u32 npages = map_size >> PAGE_SHIFT;
+       struct mlx5_user_mmap_entry *mentry;
+       struct rdma_user_mmap_entry *entry;
+       unsigned long pgoff;
+       pgprot_t prot;
        phys_addr_t pfn;
+       int ret;
 
-       if (find_next_zero_bit(mctx->dm_pages, page_idx + npages, page_idx) !=
-           page_idx + npages)
+       pgoff = mlx5_vma_to_pgoff(vma);
+       entry = rdma_user_mmap_entry_get_pgoff(ucontext, pgoff);
+       if (!entry)
                return -EINVAL;
 
-       pfn = ((dev->mdev->bar_addr +
-             MLX5_CAP64_DEV_MEM(dev->mdev, memic_bar_start_addr)) >>
-             PAGE_SHIFT) +
-             page_idx;
-       return rdma_user_mmap_io(context, vma, pfn, map_size,
-                                pgprot_writecombine(vma->vm_page_prot),
-                                NULL);
+       mentry = to_mmmap(entry);
+       pfn = (mentry->address >> PAGE_SHIFT);
+       prot = pgprot_writecombine(vma->vm_page_prot);
+       ret = rdma_user_mmap_io(ucontext, vma, pfn,
+                               entry->npages * PAGE_SIZE,
+                               prot,
+                               entry);
+       rdma_user_mmap_entry_put(&mentry->rdma_entry);
+       return ret;
 }
 
 static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
@@ -2248,11 +2295,8 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm
        case MLX5_IB_MMAP_CLOCK_INFO:
                return mlx5_ib_mmap_clock_info_page(dev, vma, context);
 
-       case MLX5_IB_MMAP_DEVICE_MEM:
-               return dm_mmap(ibcontext, vma);
-
        default:
-               return -EINVAL;
+               return mlx5_ib_mmap_offset(dev, vma, ibcontext);
        }
 
        return 0;
@@ -2288,8 +2332,9 @@ static int handle_alloc_dm_memic(struct ib_ucontext *ctx,
 {
        struct mlx5_dm *dm_db = &to_mdev(ctx->device)->dm;
        u64 start_offset;
-       u32 page_idx;
+       u16 page_idx;
        int err;
+       u64 address;
 
        dm->size = roundup(attr->length, MLX5_MEMIC_BASE_SIZE);
 
@@ -2298,28 +2343,30 @@ static int handle_alloc_dm_memic(struct ib_ucontext *ctx,
        if (err)
                return err;
 
-       page_idx = (dm->dev_addr - pci_resource_start(dm_db->dev->pdev, 0) -
-                   MLX5_CAP64_DEV_MEM(dm_db->dev, memic_bar_start_addr)) >>
-                   PAGE_SHIFT;
+       address = dm->dev_addr & PAGE_MASK;
+       err = add_dm_mmap_entry(ctx, dm, address);
+       if (err)
+               goto err_dealloc;
 
+       page_idx = dm->mentry.rdma_entry.start_pgoff & 0xFFFF;
        err = uverbs_copy_to(attrs,
                             MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX,
-                            &page_idx, sizeof(page_idx));
+                            &page_idx,
+                            sizeof(page_idx));
        if (err)
-               goto err_dealloc;
+               goto err_copy;
 
        start_offset = dm->dev_addr & ~PAGE_MASK;
        err = uverbs_copy_to(attrs,
                             MLX5_IB_ATTR_ALLOC_DM_RESP_START_OFFSET,
                             &start_offset, sizeof(start_offset));
        if (err)
-               goto err_dealloc;
-
-       bitmap_set(to_mucontext(ctx)->dm_pages, page_idx,
-                  DIV_ROUND_UP(dm->size, PAGE_SIZE));
+               goto err_copy;
 
        return 0;
 
+err_copy:
+       rdma_user_mmap_entry_remove(&dm->mentry.rdma_entry);
 err_dealloc:
        mlx5_cmd_dealloc_memic(dm_db, dm->dev_addr, dm->size);
 
@@ -2423,23 +2470,13 @@ int mlx5_ib_dealloc_dm(struct ib_dm *ibdm, struct uverbs_attr_bundle *attrs)
        struct mlx5_ib_ucontext *ctx = rdma_udata_to_drv_context(
                &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext);
        struct mlx5_core_dev *dev = to_mdev(ibdm->device)->mdev;
-       struct mlx5_dm *dm_db = &to_mdev(ibdm->device)->dm;
        struct mlx5_ib_dm *dm = to_mdm(ibdm);
-       u32 page_idx;
        int ret;
 
        switch (dm->type) {
        case MLX5_IB_UAPI_DM_TYPE_MEMIC:
-               ret = mlx5_cmd_dealloc_memic(dm_db, dm->dev_addr, dm->size);
-               if (ret)
-                       return ret;
-
-               page_idx = (dm->dev_addr - pci_resource_start(dev->pdev, 0) -
-                           MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr)) >>
-                           PAGE_SHIFT;
-               bitmap_clear(ctx->dm_pages, page_idx,
-                            DIV_ROUND_UP(dm->size, PAGE_SIZE));
-               break;
+               rdma_user_mmap_entry_remove(&dm->mentry.rdma_entry);
+               return 0;
        case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM:
                ret = mlx5_dm_sw_icm_dealloc(dev, MLX5_SW_ICM_TYPE_STEERING,
                                             dm->size, ctx->devx_uid, dm->dev_addr,
@@ -3544,10 +3581,6 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
        }
 
        INIT_LIST_HEAD(&handler->list);
-       if (dst) {
-               memcpy(&dest_arr[0], dst, sizeof(*dst));
-               dest_num++;
-       }
 
        for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
                err = parse_flow_attr(dev->mdev, spec,
@@ -3560,6 +3593,11 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
                ib_flow += ((union ib_flow_spec *)ib_flow)->size;
        }
 
+       if (dst && !(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP)) {
+               memcpy(&dest_arr[0], dst, sizeof(*dst));
+               dest_num++;
+       }
+
        if (!flow_is_multicast_only(flow_attr))
                set_underlay_qp(dev, spec, underlay_qpn);
 
@@ -3600,10 +3638,8 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
        }
 
        if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP) {
-               if (!(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT)) {
+               if (!dest_num)
                        rule_dst = NULL;
-                       dest_num = 0;
-               }
        } else {
                if (is_egress)
                        flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
@@ -6236,6 +6272,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
        .map_mr_sg = mlx5_ib_map_mr_sg,
        .map_mr_sg_pi = mlx5_ib_map_mr_sg_pi,
        .mmap = mlx5_ib_mmap,
+       .mmap_free = mlx5_ib_mmap_free,
        .modify_cq = mlx5_ib_modify_cq,
        .modify_device = mlx5_ib_modify_device,
        .modify_port = mlx5_ib_modify_port,
index 5986953..b06f32f 100644 (file)
@@ -118,6 +118,10 @@ enum {
        MLX5_MEMIC_BASE_SIZE    = 1 << MLX5_MEMIC_BASE_ALIGN,
 };
 
+enum mlx5_ib_mmap_type {
+       MLX5_IB_MMAP_TYPE_MEMIC = 1,
+};
+
 #define MLX5_LOG_SW_ICM_BLOCK_SIZE(dev)                                        \
        (MLX5_CAP_DEV_MEM(dev, log_sw_icm_alloc_granularity))
 #define MLX5_SW_ICM_BLOCK_SIZE(dev) (1 << MLX5_LOG_SW_ICM_BLOCK_SIZE(dev))
@@ -135,7 +139,6 @@ struct mlx5_ib_ucontext {
        u32                     tdn;
 
        u64                     lib_caps;
-       DECLARE_BITMAP(dm_pages, MLX5_MAX_MEMIC_PAGES);
        u16                     devx_uid;
        /* For RoCE LAG TX affinity */
        atomic_t                tx_port_affinity;
@@ -556,6 +559,12 @@ enum mlx5_ib_mtt_access_flags {
        MLX5_IB_MTT_WRITE = (1 << 1),
 };
 
+struct mlx5_user_mmap_entry {
+       struct rdma_user_mmap_entry rdma_entry;
+       u8 mmap_flag;
+       u64 address;
+};
+
 struct mlx5_ib_dm {
        struct ib_dm            ibdm;
        phys_addr_t             dev_addr;
@@ -567,6 +576,7 @@ struct mlx5_ib_dm {
                } icm_dm;
                /* other dm types specific params should be added here */
        };
+       struct mlx5_user_mmap_entry mentry;
 };
 
 #define MLX5_IB_MTT_PRESENT (MLX5_IB_MTT_READ | MLX5_IB_MTT_WRITE)
@@ -1101,6 +1111,13 @@ to_mflow_act(struct ib_flow_action *ibact)
        return container_of(ibact, struct mlx5_ib_flow_action, ib_action);
 }
 
+static inline struct mlx5_user_mmap_entry *
+to_mmmap(struct rdma_user_mmap_entry *rdma_entry)
+{
+       return container_of(rdma_entry,
+               struct mlx5_user_mmap_entry, rdma_entry);
+}
+
 int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context,
                        struct ib_udata *udata, unsigned long virt,
                        struct mlx5_db *db);
index 5a3474f..312c2fc 100644 (file)
@@ -117,10 +117,12 @@ static struct dst_entry *rxe_find_route6(struct net_device *ndev,
        memcpy(&fl6.daddr, daddr, sizeof(*daddr));
        fl6.flowi6_proto = IPPROTO_UDP;
 
-       if (unlikely(ipv6_stub->ipv6_dst_lookup(sock_net(recv_sockets.sk6->sk),
-                                               recv_sockets.sk6->sk, &ndst, &fl6))) {
+       ndst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(recv_sockets.sk6->sk),
+                                              recv_sockets.sk6->sk, &fl6,
+                                              NULL);
+       if (unlikely(IS_ERR(ndst))) {
                pr_err_ratelimited("no route to %pI6\n", daddr);
-               goto put;
+               return NULL;
        }
 
        if (unlikely(ndst->error)) {
index f9a492e..831ad57 100644 (file)
@@ -389,7 +389,7 @@ void rxe_rcv(struct sk_buff *skb)
 
        calc_icrc = rxe_icrc_hdr(pkt, skb);
        calc_icrc = rxe_crc32(rxe, calc_icrc, (u8 *)payload_addr(pkt),
-                             payload_size(pkt));
+                             payload_size(pkt) + bth_pad(pkt));
        calc_icrc = (__force u32)cpu_to_be32(~calc_icrc);
        if (unlikely(calc_icrc != pack_icrc)) {
                if (skb->protocol == htons(ETH_P_IPV6))
index c5d9b55..e503117 100644 (file)
@@ -500,6 +500,12 @@ static int fill_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
                        if (err)
                                return err;
                }
+               if (bth_pad(pkt)) {
+                       u8 *pad = payload_addr(pkt) + paylen;
+
+                       memset(pad, 0, bth_pad(pkt));
+                       crc = rxe_crc32(rxe, crc, pad, bth_pad(pkt));
+               }
        }
        p = payload_addr(pkt) + paylen + bth_pad(pkt);
 
index 1cbfbd9..c4a8195 100644 (file)
@@ -732,6 +732,13 @@ static enum resp_states read_reply(struct rxe_qp *qp,
        if (err)
                pr_err("Failed copying memory\n");
 
+       if (bth_pad(&ack_pkt)) {
+               struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
+               u8 *pad = payload_addr(&ack_pkt) + payload;
+
+               memset(pad, 0, bth_pad(&ack_pkt));
+               icrc = rxe_crc32(rxe, icrc, pad, bth_pad(&ack_pkt));
+       }
        p = payload_addr(&ack_pkt) + payload + bth_pad(&ack_pkt);
        *p = ~icrc;
 
index 62390e9..8ad7da9 100644 (file)
@@ -63,7 +63,7 @@ struct vnic_stats {
        };
 };
 
-#define VNIC_STAT(m)            { FIELD_SIZEOF(struct opa_vnic_stats, m),   \
+#define VNIC_STAT(m)            { sizeof_field(struct opa_vnic_stats, m),   \
                                  offsetof(struct opa_vnic_stats, m) }
 
 static struct vnic_stats vnic_gstrings_stats[] = {
index 61f4eb6..4706ff0 100644 (file)
@@ -450,7 +450,7 @@ config KEYBOARD_SNVS_PWRKEY
        depends on OF
        help
          This is the snvs powerkey driver for the Freescale i.MX application
-         processors that are newer than i.MX6 SX.
+         processors.
 
          To compile this driver as a module, choose M here; the
          module will be called snvs_pwrkey.
index e76b7a4..2f5e3ab 100644 (file)
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 
-#define SNVS_LPSR_REG  0x4C    /* LP Status Register */
-#define SNVS_LPCR_REG  0x38    /* LP Control Register */
-#define SNVS_HPSR_REG  0x14
-#define SNVS_HPSR_BTN  BIT(6)
-#define SNVS_LPSR_SPO  BIT(18)
-#define SNVS_LPCR_DEP_EN BIT(5)
+#define SNVS_HPVIDR1_REG       0xF8
+#define SNVS_LPSR_REG          0x4C    /* LP Status Register */
+#define SNVS_LPCR_REG          0x38    /* LP Control Register */
+#define SNVS_HPSR_REG          0x14
+#define SNVS_HPSR_BTN          BIT(6)
+#define SNVS_LPSR_SPO          BIT(18)
+#define SNVS_LPCR_DEP_EN       BIT(5)
 
-#define DEBOUNCE_TIME 30
-#define REPEAT_INTERVAL 60
+#define DEBOUNCE_TIME          30
+#define REPEAT_INTERVAL                60
 
 struct pwrkey_drv_data {
        struct regmap *snvs;
@@ -37,6 +38,7 @@ struct pwrkey_drv_data {
        int wakeup;
        struct timer_list check_timer;
        struct input_dev *input;
+       u8 minor_rev;
 };
 
 static void imx_imx_snvs_check_for_events(struct timer_list *t)
@@ -67,13 +69,29 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = dev_id;
        struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+       struct input_dev *input = pdata->input;
        u32 lp_status;
 
-       pm_wakeup_event(pdata->input->dev.parent, 0);
+       pm_wakeup_event(input->dev.parent, 0);
 
        regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status);
-       if (lp_status & SNVS_LPSR_SPO)
-               mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
+       if (lp_status & SNVS_LPSR_SPO) {
+               if (pdata->minor_rev == 0) {
+                       /*
+                        * The first generation i.MX6 SoCs only sends an
+                        * interrupt on button release. To mimic power-key
+                        * usage, we'll prepend a press event.
+                        */
+                       input_report_key(input, pdata->keycode, 1);
+                       input_sync(input);
+                       input_report_key(input, pdata->keycode, 0);
+                       input_sync(input);
+                       pm_relax(input->dev.parent);
+               } else {
+                       mod_timer(&pdata->check_timer,
+                                 jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
+               }
+       }
 
        /* clear SPO status */
        regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
@@ -90,10 +108,11 @@ static void imx_snvs_pwrkey_act(void *pdata)
 
 static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 {
-       struct pwrkey_drv_data *pdata = NULL;
-       struct input_dev *input = NULL;
+       struct pwrkey_drv_data *pdata;
+       struct input_dev *input;
        struct device_node *np;
        int error;
+       u32 vid;
 
        /* Get SNVS register Page */
        np = pdev->dev.of_node;
@@ -121,6 +140,9 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
        if (pdata->irq < 0)
                return -EINVAL;
 
+       regmap_read(pdata->snvs, SNVS_HPVIDR1_REG, &vid);
+       pdata->minor_rev = vid & 0xff;
+
        regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN);
 
        /* clear the unexpected interrupt before driver ready */
index 84051f2..fd25378 100644 (file)
@@ -695,7 +695,7 @@ static __poll_t uinput_poll(struct file *file, poll_table *wait)
        if (udev->head != udev->tail)
                return EPOLLIN | EPOLLRDNORM;
 
-       return 0;
+       return EPOLLOUT | EPOLLWRNORM;
 }
 
 static int uinput_release(struct inode *inode, struct file *file)
index a4cabf5..74f7c6f 100644 (file)
@@ -1189,6 +1189,9 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw)
 {
        int ret;
 
+       f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev,
+                                              f34->fn->irq_mask);
+
        rmi_f34v7_read_queries_bl_version(f34);
 
        f34->v7.image = fw->data;
index 2407ea4..b313c57 100644 (file)
@@ -163,7 +163,6 @@ static int rmi_smb_write_block(struct rmi_transport_dev *xport, u16 rmiaddr,
                /* prepare to write next block of bytes */
                cur_len -= SMB_MAX_COUNT;
                databuff += SMB_MAX_COUNT;
-               rmiaddr += SMB_MAX_COUNT;
        }
 exit:
        mutex_unlock(&rmi_smb->page_mutex);
@@ -215,7 +214,6 @@ static int rmi_smb_read_block(struct rmi_transport_dev *xport, u16 rmiaddr,
                /* prepare to read next block of bytes */
                cur_len -= SMB_MAX_COUNT;
                databuff += SMB_MAX_COUNT;
-               rmiaddr += SMB_MAX_COUNT;
        }
 
        retval = 0;
index fb43aa7..0403102 100644 (file)
@@ -129,6 +129,15 @@ static const unsigned long goodix_irq_flags[] = {
 static const struct dmi_system_id rotated_screen[] = {
 #if defined(CONFIG_DMI) && defined(CONFIG_X86)
        {
+               .ident = "Teclast X89",
+               .matches = {
+                       /* tPAD is too generic, also match on bios date */
+                       DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
+                       DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
+                       DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"),
+               },
+       },
+       {
                .ident = "WinBook TW100",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
index c49afbe..2f9304d 100644 (file)
@@ -6,13 +6,13 @@ config INTERCONNECT_QCOM
          Support for Qualcomm's Network-on-Chip interconnect hardware.
 
 config INTERCONNECT_QCOM_MSM8974
-       tristate "Qualcomm MSM8974 interconnect driver"
-       depends on INTERCONNECT_QCOM
-       depends on QCOM_SMD_RPM
-       select INTERCONNECT_QCOM_SMD_RPM
-       help
-         This is a driver for the Qualcomm Network-on-Chip on msm8974-based
-         platforms.
+       tristate "Qualcomm MSM8974 interconnect driver"
+       depends on INTERCONNECT_QCOM
+       depends on QCOM_SMD_RPM
+       select INTERCONNECT_QCOM_SMD_RPM
+       help
+        This is a driver for the Qualcomm Network-on-Chip on msm8974-based
+        platforms.
 
 config INTERCONNECT_QCOM_QCS404
        tristate "Qualcomm QCS404 interconnect driver"
index ce599a0..bf8bd1a 100644 (file)
@@ -652,7 +652,7 @@ static int msm8974_icc_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct icc_onecell_data *data;
        struct icc_provider *provider;
-       struct icc_node *node;
+       struct icc_node *node, *tmp;
        size_t num_nodes, i;
        int ret;
 
@@ -732,7 +732,7 @@ static int msm8974_icc_probe(struct platform_device *pdev)
        return 0;
 
 err_del_icc:
-       list_for_each_entry(node, &provider->nodes, node_list) {
+       list_for_each_entry_safe(node, tmp, &provider->nodes, node_list) {
                icc_node_del(node);
                icc_node_destroy(node->id);
        }
@@ -748,9 +748,9 @@ static int msm8974_icc_remove(struct platform_device *pdev)
 {
        struct msm8974_icc_provider *qp = platform_get_drvdata(pdev);
        struct icc_provider *provider = &qp->provider;
-       struct icc_node *n;
+       struct icc_node *n, *tmp;
 
-       list_for_each_entry(n, &provider->nodes, node_list) {
+       list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) {
                icc_node_del(n);
                icc_node_destroy(n->id);
        }
index b4966d8..8e0735a 100644 (file)
@@ -414,7 +414,7 @@ static int qnoc_probe(struct platform_device *pdev)
        struct icc_provider *provider;
        struct qcom_icc_node **qnodes;
        struct qcom_icc_provider *qp;
-       struct icc_node *node;
+       struct icc_node *node, *tmp;
        size_t num_nodes, i;
        int ret;
 
@@ -494,7 +494,7 @@ static int qnoc_probe(struct platform_device *pdev)
 
        return 0;
 err:
-       list_for_each_entry(node, &provider->nodes, node_list) {
+       list_for_each_entry_safe(node, tmp, &provider->nodes, node_list) {
                icc_node_del(node);
                icc_node_destroy(node->id);
        }
@@ -508,9 +508,9 @@ static int qnoc_remove(struct platform_device *pdev)
 {
        struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
        struct icc_provider *provider = &qp->provider;
-       struct icc_node *n;
+       struct icc_node *n, *tmp;
 
-       list_for_each_entry(n, &provider->nodes, node_list) {
+       list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) {
                icc_node_del(n);
                icc_node_destroy(n->id);
        }
index 502a6c2..387267e 100644 (file)
@@ -868,9 +868,9 @@ static int qnoc_remove(struct platform_device *pdev)
 {
        struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
        struct icc_provider *provider = &qp->provider;
-       struct icc_node *n;
+       struct icc_node *n, *tmp;
 
-       list_for_each_entry(n, &provider->nodes, node_list) {
+       list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) {
                icc_node_del(n);
                icc_node_destroy(n->id);
        }
index db7bfd4..1c3f2a3 100644 (file)
@@ -312,8 +312,8 @@ int iommu_insert_resv_region(struct iommu_resv_region *new,
        list_for_each_entry_safe(iter, tmp, regions, list) {
                phys_addr_t top_end, iter_end = iter->start + iter->length - 1;
 
-               /* no merge needed on elements of different types than @nr */
-               if (iter->type != nr->type) {
+               /* no merge needed on elements of different types than @new */
+               if (iter->type != new->type) {
                        list_move_tail(&iter->list, &stack);
                        continue;
                }
index 08c552e..c05b121 100644 (file)
@@ -67,23 +67,34 @@ struct superblock_disk {
  * To save constantly doing look ups on disk we keep an in core copy of the
  * on-disk bitmap, the region_map.
  *
- * To further reduce metadata I/O overhead we use a second bitmap, the dmap
- * (dirty bitmap), which tracks the dirty words, i.e. longs, of the region_map.
+ * In order to track which regions are hydrated during a metadata transaction,
+ * we use a second set of bitmaps, the dmap (dirty bitmap), which includes two
+ * bitmaps, namely dirty_regions and dirty_words. The dirty_regions bitmap
+ * tracks the regions that got hydrated during the current metadata
+ * transaction. The dirty_words bitmap tracks the dirty words, i.e. longs, of
+ * the dirty_regions bitmap.
+ *
+ * This allows us to precisely track the regions that were hydrated during the
+ * current metadata transaction and update the metadata accordingly, when we
+ * commit the current transaction. This is important because dm-clone should
+ * only commit the metadata of regions that were properly flushed to the
+ * destination device beforehand. Otherwise, in case of a crash, we could end
+ * up with a corrupted dm-clone device.
  *
  * When a region finishes hydrating dm-clone calls
  * dm_clone_set_region_hydrated(), or for discard requests
  * dm_clone_cond_set_range(), which sets the corresponding bits in region_map
  * and dmap.
  *
- * During a metadata commit we scan the dmap for dirty region_map words (longs)
- * and update accordingly the on-disk metadata. Thus, we don't have to flush to
- * disk the whole region_map. We can just flush the dirty region_map words.
+ * During a metadata commit we scan dmap->dirty_words and dmap->dirty_regions
+ * and update the on-disk metadata accordingly. Thus, we don't have to flush to
+ * disk the whole region_map. We can just flush the dirty region_map bits.
  *
- * We use a dirty bitmap, which is smaller than the original region_map, to
- * reduce the amount of memory accesses during a metadata commit. As dm-bitset
- * accesses the on-disk bitmap in 64-bit word granularity, there is no
- * significant benefit in tracking the dirty region_map bits with a smaller
- * granularity.
+ * We use the helper dmap->dirty_words bitmap, which is smaller than the
+ * original region_map, to reduce the amount of memory accesses during a
+ * metadata commit. Moreover, as dm-bitset also accesses the on-disk bitmap in
+ * 64-bit word granularity, the dirty_words bitmap helps us avoid useless disk
+ * accesses.
  *
  * We could update directly the on-disk bitmap, when dm-clone calls either
  * dm_clone_set_region_hydrated() or dm_clone_cond_set_range(), buts this
@@ -92,12 +103,13 @@ struct superblock_disk {
  * e.g., in a hooked overwrite bio's completion routine, and further reduce the
  * I/O completion latency.
  *
- * We maintain two dirty bitmaps. During a metadata commit we atomically swap
- * the currently used dmap with the unused one. This allows the metadata update
- * functions to run concurrently with an ongoing commit.
+ * We maintain two dirty bitmap sets. During a metadata commit we atomically
+ * swap the currently used dmap with the unused one. This allows the metadata
+ * update functions to run concurrently with an ongoing commit.
  */
 struct dirty_map {
        unsigned long *dirty_words;
+       unsigned long *dirty_regions;
        unsigned int changed;
 };
 
@@ -115,6 +127,9 @@ struct dm_clone_metadata {
        struct dirty_map dmap[2];
        struct dirty_map *current_dmap;
 
+       /* Protected by lock */
+       struct dirty_map *committing_dmap;
+
        /*
         * In core copy of the on-disk bitmap to save constantly doing look ups
         * on disk.
@@ -461,34 +476,53 @@ static size_t bitmap_size(unsigned long nr_bits)
        return BITS_TO_LONGS(nr_bits) * sizeof(long);
 }
 
-static int dirty_map_init(struct dm_clone_metadata *cmd)
+static int __dirty_map_init(struct dirty_map *dmap, unsigned long nr_words,
+                           unsigned long nr_regions)
 {
-       cmd->dmap[0].changed = 0;
-       cmd->dmap[0].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL);
+       dmap->changed = 0;
 
-       if (!cmd->dmap[0].dirty_words) {
-               DMERR("Failed to allocate dirty bitmap");
+       dmap->dirty_words = kvzalloc(bitmap_size(nr_words), GFP_KERNEL);
+       if (!dmap->dirty_words)
+               return -ENOMEM;
+
+       dmap->dirty_regions = kvzalloc(bitmap_size(nr_regions), GFP_KERNEL);
+       if (!dmap->dirty_regions) {
+               kvfree(dmap->dirty_words);
                return -ENOMEM;
        }
 
-       cmd->dmap[1].changed = 0;
-       cmd->dmap[1].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL);
+       return 0;
+}
+
+static void __dirty_map_exit(struct dirty_map *dmap)
+{
+       kvfree(dmap->dirty_words);
+       kvfree(dmap->dirty_regions);
+}
+
+static int dirty_map_init(struct dm_clone_metadata *cmd)
+{
+       if (__dirty_map_init(&cmd->dmap[0], cmd->nr_words, cmd->nr_regions)) {
+               DMERR("Failed to allocate dirty bitmap");
+               return -ENOMEM;
+       }
 
-       if (!cmd->dmap[1].dirty_words) {
+       if (__dirty_map_init(&cmd->dmap[1], cmd->nr_words, cmd->nr_regions)) {
                DMERR("Failed to allocate dirty bitmap");
-               kvfree(cmd->dmap[0].dirty_words);
+               __dirty_map_exit(&cmd->dmap[0]);
                return -ENOMEM;
        }
 
        cmd->current_dmap = &cmd->dmap[0];
+       cmd->committing_dmap = NULL;
 
        return 0;
 }
 
 static void dirty_map_exit(struct dm_clone_metadata *cmd)
 {
-       kvfree(cmd->dmap[0].dirty_words);
-       kvfree(cmd->dmap[1].dirty_words);
+       __dirty_map_exit(&cmd->dmap[0]);
+       __dirty_map_exit(&cmd->dmap[1]);
 }
 
 static int __load_bitset_in_core(struct dm_clone_metadata *cmd)
@@ -633,21 +667,23 @@ unsigned long dm_clone_find_next_unhydrated_region(struct dm_clone_metadata *cmd
        return find_next_zero_bit(cmd->region_map, cmd->nr_regions, start);
 }
 
-static int __update_metadata_word(struct dm_clone_metadata *cmd, unsigned long word)
+static int __update_metadata_word(struct dm_clone_metadata *cmd,
+                                 unsigned long *dirty_regions,
+                                 unsigned long word)
 {
        int r;
        unsigned long index = word * BITS_PER_LONG;
        unsigned long max_index = min(cmd->nr_regions, (word + 1) * BITS_PER_LONG);
 
        while (index < max_index) {
-               if (test_bit(index, cmd->region_map)) {
+               if (test_bit(index, dirty_regions)) {
                        r = dm_bitset_set_bit(&cmd->bitset_info, cmd->bitset_root,
                                              index, &cmd->bitset_root);
-
                        if (r) {
                                DMERR("dm_bitset_set_bit failed");
                                return r;
                        }
+                       __clear_bit(index, dirty_regions);
                }
                index++;
        }
@@ -721,7 +757,7 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap)
                if (word == cmd->nr_words)
                        break;
 
-               r = __update_metadata_word(cmd, word);
+               r = __update_metadata_word(cmd, dmap->dirty_regions, word);
 
                if (r)
                        return r;
@@ -743,15 +779,17 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap)
        return 0;
 }
 
-int dm_clone_metadata_commit(struct dm_clone_metadata *cmd)
+int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd)
 {
-       int r = -EPERM;
+       int r = 0;
        struct dirty_map *dmap, *next_dmap;
 
        down_write(&cmd->lock);
 
-       if (cmd->fail_io || dm_bm_is_read_only(cmd->bm))
+       if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) {
+               r = -EPERM;
                goto out;
+       }
 
        /* Get current dirty bitmap */
        dmap = cmd->current_dmap;
@@ -763,7 +801,7 @@ int dm_clone_metadata_commit(struct dm_clone_metadata *cmd)
         * The last commit failed, so we don't have a clean dirty-bitmap to
         * use.
         */
-       if (WARN_ON(next_dmap->changed)) {
+       if (WARN_ON(next_dmap->changed || cmd->committing_dmap)) {
                r = -EINVAL;
                goto out;
        }
@@ -773,11 +811,33 @@ int dm_clone_metadata_commit(struct dm_clone_metadata *cmd)
        cmd->current_dmap = next_dmap;
        spin_unlock_irq(&cmd->bitmap_lock);
 
-       /*
-        * No one is accessing the old dirty bitmap anymore, so we can flush
-        * it.
-        */
-       r = __flush_dmap(cmd, dmap);
+       /* Set old dirty bitmap as currently committing */
+       cmd->committing_dmap = dmap;
+out:
+       up_write(&cmd->lock);
+
+       return r;
+}
+
+int dm_clone_metadata_commit(struct dm_clone_metadata *cmd)
+{
+       int r = -EPERM;
+
+       down_write(&cmd->lock);
+
+       if (cmd->fail_io || dm_bm_is_read_only(cmd->bm))
+               goto out;
+
+       if (WARN_ON(!cmd->committing_dmap)) {
+               r = -EINVAL;
+               goto out;
+       }
+
+       r = __flush_dmap(cmd, cmd->committing_dmap);
+       if (!r) {
+               /* Clear committing dmap */
+               cmd->committing_dmap = NULL;
+       }
 out:
        up_write(&cmd->lock);
 
@@ -802,6 +862,7 @@ int dm_clone_set_region_hydrated(struct dm_clone_metadata *cmd, unsigned long re
        dmap = cmd->current_dmap;
 
        __set_bit(word, dmap->dirty_words);
+       __set_bit(region_nr, dmap->dirty_regions);
        __set_bit(region_nr, cmd->region_map);
        dmap->changed = 1;
 
@@ -830,6 +891,7 @@ int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start,
                if (!test_bit(region_nr, cmd->region_map)) {
                        word = region_nr / BITS_PER_LONG;
                        __set_bit(word, dmap->dirty_words);
+                       __set_bit(region_nr, dmap->dirty_regions);
                        __set_bit(region_nr, cmd->region_map);
                        dmap->changed = 1;
                }
index 3fe50a7..14af1eb 100644 (file)
@@ -75,7 +75,23 @@ void dm_clone_metadata_close(struct dm_clone_metadata *cmd);
 
 /*
  * Commit dm-clone metadata to disk.
+ *
+ * We use a two phase commit:
+ *
+ * 1. dm_clone_metadata_pre_commit(): Prepare the current transaction for
+ *    committing. After this is called, all subsequent metadata updates, done
+ *    through either dm_clone_set_region_hydrated() or
+ *    dm_clone_cond_set_range(), will be part of the **next** transaction.
+ *
+ * 2. dm_clone_metadata_commit(): Actually commit the current transaction to
+ *    disk and start a new transaction.
+ *
+ * This allows dm-clone to flush the destination device after step (1) to
+ * ensure that all freshly hydrated regions, for which we are updating the
+ * metadata, are properly written to non-volatile storage and won't be lost in
+ * case of a crash.
  */
+int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd);
 int dm_clone_metadata_commit(struct dm_clone_metadata *cmd);
 
 /*
@@ -112,6 +128,7 @@ int dm_clone_metadata_abort(struct dm_clone_metadata *cmd);
  * Switches metadata to a read only mode. Once read-only mode has been entered
  * the following functions will return -EPERM:
  *
+ *   dm_clone_metadata_pre_commit()
  *   dm_clone_metadata_commit()
  *   dm_clone_set_region_hydrated()
  *   dm_clone_cond_set_range()
index b3d8907..d1e1b5b 100644 (file)
@@ -86,6 +86,12 @@ struct clone {
 
        struct dm_clone_metadata *cmd;
 
+       /*
+        * bio used to flush the destination device, before committing the
+        * metadata.
+        */
+       struct bio flush_bio;
+
        /* Region hydration hash table */
        struct hash_table_bucket *ht;
 
@@ -1108,10 +1114,13 @@ static bool need_commit_due_to_time(struct clone *clone)
 /*
  * A non-zero return indicates read-only or fail mode.
  */
-static int commit_metadata(struct clone *clone)
+static int commit_metadata(struct clone *clone, bool *dest_dev_flushed)
 {
        int r = 0;
 
+       if (dest_dev_flushed)
+               *dest_dev_flushed = false;
+
        mutex_lock(&clone->commit_lock);
 
        if (!dm_clone_changed_this_transaction(clone->cmd))
@@ -1122,8 +1131,26 @@ static int commit_metadata(struct clone *clone)
                goto out;
        }
 
-       r = dm_clone_metadata_commit(clone->cmd);
+       r = dm_clone_metadata_pre_commit(clone->cmd);
+       if (unlikely(r)) {
+               __metadata_operation_failed(clone, "dm_clone_metadata_pre_commit", r);
+               goto out;
+       }
 
+       bio_reset(&clone->flush_bio);
+       bio_set_dev(&clone->flush_bio, clone->dest_dev->bdev);
+       clone->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
+
+       r = submit_bio_wait(&clone->flush_bio);
+       if (unlikely(r)) {
+               __metadata_operation_failed(clone, "flush destination device", r);
+               goto out;
+       }
+
+       if (dest_dev_flushed)
+               *dest_dev_flushed = true;
+
+       r = dm_clone_metadata_commit(clone->cmd);
        if (unlikely(r)) {
                __metadata_operation_failed(clone, "dm_clone_metadata_commit", r);
                goto out;
@@ -1194,6 +1221,7 @@ static void process_deferred_bios(struct clone *clone)
 static void process_deferred_flush_bios(struct clone *clone)
 {
        struct bio *bio;
+       bool dest_dev_flushed;
        struct bio_list bios = BIO_EMPTY_LIST;
        struct bio_list bio_completions = BIO_EMPTY_LIST;
 
@@ -1213,7 +1241,7 @@ static void process_deferred_flush_bios(struct clone *clone)
            !(dm_clone_changed_this_transaction(clone->cmd) && need_commit_due_to_time(clone)))
                return;
 
-       if (commit_metadata(clone)) {
+       if (commit_metadata(clone, &dest_dev_flushed)) {
                bio_list_merge(&bios, &bio_completions);
 
                while ((bio = bio_list_pop(&bios)))
@@ -1227,8 +1255,17 @@ static void process_deferred_flush_bios(struct clone *clone)
        while ((bio = bio_list_pop(&bio_completions)))
                bio_endio(bio);
 
-       while ((bio = bio_list_pop(&bios)))
-               generic_make_request(bio);
+       while ((bio = bio_list_pop(&bios))) {
+               if ((bio->bi_opf & REQ_PREFLUSH) && dest_dev_flushed) {
+                       /* We just flushed the destination device as part of
+                        * the metadata commit, so there is no reason to send
+                        * another flush.
+                        */
+                       bio_endio(bio);
+               } else {
+                       generic_make_request(bio);
+               }
+       }
 }
 
 static void do_worker(struct work_struct *work)
@@ -1400,7 +1437,7 @@ static void clone_status(struct dm_target *ti, status_type_t type,
 
                /* Commit to ensure statistics aren't out-of-date */
                if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti))
-                       (void) commit_metadata(clone);
+                       (void) commit_metadata(clone, NULL);
 
                r = dm_clone_get_free_metadata_block_count(clone->cmd, &nr_free_metadata_blocks);
 
@@ -1834,6 +1871,7 @@ static int clone_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        bio_list_init(&clone->deferred_flush_completions);
        clone->hydration_offset = 0;
        atomic_set(&clone->hydrations_in_flight, 0);
+       bio_init(&clone->flush_bio, NULL, 0);
 
        clone->wq = alloc_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM, 0);
        if (!clone->wq) {
@@ -1907,6 +1945,7 @@ static void clone_dtr(struct dm_target *ti)
        struct clone *clone = ti->private;
 
        mutex_destroy(&clone->commit_lock);
+       bio_uninit(&clone->flush_bio);
 
        for (i = 0; i < clone->nr_ctr_args; i++)
                kfree(clone->ctr_args[i]);
@@ -1961,7 +2000,7 @@ static void clone_postsuspend(struct dm_target *ti)
        wait_event(clone->hydration_stopped, !atomic_read(&clone->hydrations_in_flight));
        flush_workqueue(clone->wq);
 
-       (void) commit_metadata(clone);
+       (void) commit_metadata(clone, NULL);
 }
 
 static void clone_resume(struct dm_target *ti)
index dbcc1e4..e0c3279 100644 (file)
@@ -599,45 +599,10 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio)
        return pgpath;
 }
 
-static struct pgpath *__map_bio_fast(struct multipath *m, struct bio *bio)
-{
-       struct pgpath *pgpath;
-       unsigned long flags;
-
-       /* Do we need to select a new pgpath? */
-       /*
-        * FIXME: currently only switching path if no path (due to failure, etc)
-        * - which negates the point of using a path selector
-        */
-       pgpath = READ_ONCE(m->current_pgpath);
-       if (!pgpath)
-               pgpath = choose_pgpath(m, bio->bi_iter.bi_size);
-
-       if (!pgpath) {
-               if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
-                       /* Queue for the daemon to resubmit */
-                       spin_lock_irqsave(&m->lock, flags);
-                       bio_list_add(&m->queued_bios, bio);
-                       spin_unlock_irqrestore(&m->lock, flags);
-                       queue_work(kmultipathd, &m->process_queued_bios);
-
-                       return ERR_PTR(-EAGAIN);
-               }
-               return NULL;
-       }
-
-       return pgpath;
-}
-
 static int __multipath_map_bio(struct multipath *m, struct bio *bio,
                               struct dm_mpath_io *mpio)
 {
-       struct pgpath *pgpath;
-
-       if (!m->hw_handler_name)
-               pgpath = __map_bio_fast(m, bio);
-       else
-               pgpath = __map_bio(m, bio);
+       struct pgpath *pgpath = __map_bio(m, bio);
 
        if (IS_ERR(pgpath))
                return DM_MAPIO_SUBMITTED;
index 2ae0c19..0a2cc19 100644 (file)
@@ -1954,12 +1954,14 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
        /*
         * For a zoned target, the number of zones should be updated for the
         * correct value to be exposed in sysfs queue/nr_zones. For a BIO based
-        * target, this is all that is needed. For a request based target, the
-        * queue zone bitmaps must also be updated.
-        * Use blk_revalidate_disk_zones() to handle this.
+        * target, this is all that is needed.
         */
-       if (blk_queue_is_zoned(q))
-               blk_revalidate_disk_zones(t->md->disk);
+#ifdef CONFIG_BLK_DEV_ZONED
+       if (blk_queue_is_zoned(q)) {
+               WARN_ON_ONCE(queue_is_mq(q));
+               q->nr_zones = blkdev_nr_zones(t->md->disk);
+       }
+#endif
 
        /* Allow reads to exceed readahead limits */
        q->backing_dev_info->io_pages = limits->max_sectors >> (PAGE_SHIFT - 9);
index 4c68a7b..b88d6d7 100644 (file)
@@ -189,6 +189,15 @@ struct dm_pool_metadata {
        sector_t data_block_size;
 
        /*
+        * Pre-commit callback.
+        *
+        * This allows the thin provisioning target to run a callback before
+        * the metadata are committed.
+        */
+       dm_pool_pre_commit_fn pre_commit_fn;
+       void *pre_commit_context;
+
+       /*
         * We reserve a section of the metadata for commit overhead.
         * All reported space does *not* include this.
         */
@@ -826,6 +835,14 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
        if (unlikely(!pmd->in_service))
                return 0;
 
+       if (pmd->pre_commit_fn) {
+               r = pmd->pre_commit_fn(pmd->pre_commit_context);
+               if (r < 0) {
+                       DMERR("pre-commit callback failed");
+                       return r;
+               }
+       }
+
        r = __write_changed_details(pmd);
        if (r < 0)
                return r;
@@ -892,6 +909,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
        pmd->in_service = false;
        pmd->bdev = bdev;
        pmd->data_block_size = data_block_size;
+       pmd->pre_commit_fn = NULL;
+       pmd->pre_commit_context = NULL;
 
        r = __create_persistent_data_objects(pmd, format_device);
        if (r) {
@@ -2044,6 +2063,16 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
        return r;
 }
 
+void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd,
+                                         dm_pool_pre_commit_fn fn,
+                                         void *context)
+{
+       pmd_write_lock_in_core(pmd);
+       pmd->pre_commit_fn = fn;
+       pmd->pre_commit_context = context;
+       pmd_write_unlock(pmd);
+}
+
 int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd)
 {
        int r = -EINVAL;
index f6be0d7..7ef56bd 100644 (file)
@@ -230,6 +230,13 @@ bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd);
  */
 void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd);
 
+/* Pre-commit callback */
+typedef int (*dm_pool_pre_commit_fn)(void *context);
+
+void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd,
+                                         dm_pool_pre_commit_fn fn,
+                                         void *context);
+
 /*----------------------------------------------------------------*/
 
 #endif
index 5a2c494..57626c2 100644 (file)
@@ -328,6 +328,7 @@ struct pool_c {
        dm_block_t low_water_blocks;
        struct pool_features requested_pf; /* Features requested during table load */
        struct pool_features adjusted_pf;  /* Features used after adjusting for constituent devices */
+       struct bio flush_bio;
 };
 
 /*
@@ -2383,8 +2384,16 @@ static void process_deferred_bios(struct pool *pool)
        while ((bio = bio_list_pop(&bio_completions)))
                bio_endio(bio);
 
-       while ((bio = bio_list_pop(&bios)))
-               generic_make_request(bio);
+       while ((bio = bio_list_pop(&bios))) {
+               /*
+                * The data device was flushed as part of metadata commit,
+                * so complete redundant flushes immediately.
+                */
+               if (bio->bi_opf & REQ_PREFLUSH)
+                       bio_endio(bio);
+               else
+                       generic_make_request(bio);
+       }
 }
 
 static void do_worker(struct work_struct *ws)
@@ -3115,6 +3124,7 @@ static void pool_dtr(struct dm_target *ti)
        __pool_dec(pt->pool);
        dm_put_device(ti, pt->metadata_dev);
        dm_put_device(ti, pt->data_dev);
+       bio_uninit(&pt->flush_bio);
        kfree(pt);
 
        mutex_unlock(&dm_thin_pool_table.mutex);
@@ -3180,6 +3190,29 @@ static void metadata_low_callback(void *context)
        dm_table_event(pool->ti->table);
 }
 
+/*
+ * We need to flush the data device **before** committing the metadata.
+ *
+ * This ensures that the data blocks of any newly inserted mappings are
+ * properly written to non-volatile storage and won't be lost in case of a
+ * crash.
+ *
+ * Failure to do so can result in data corruption in the case of internal or
+ * external snapshots and in the case of newly provisioned blocks, when block
+ * zeroing is enabled.
+ */
+static int metadata_pre_commit_callback(void *context)
+{
+       struct pool_c *pt = context;
+       struct bio *flush_bio = &pt->flush_bio;
+
+       bio_reset(flush_bio);
+       bio_set_dev(flush_bio, pt->data_dev->bdev);
+       flush_bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
+
+       return submit_bio_wait(flush_bio);
+}
+
 static sector_t get_dev_size(struct block_device *bdev)
 {
        return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
@@ -3348,6 +3381,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        pt->data_dev = data_dev;
        pt->low_water_blocks = low_water_blocks;
        pt->adjusted_pf = pt->requested_pf = pf;
+       bio_init(&pt->flush_bio, NULL, 0);
        ti->num_flush_bios = 1;
 
        /*
@@ -3374,6 +3408,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        if (r)
                goto out_flags_changed;
 
+       dm_pool_register_pre_commit_callback(pt->pool->pmd,
+                                            metadata_pre_commit_callback,
+                                            pt);
+
        pt->callbacks.congested_fn = pool_is_congested;
        dm_table_add_target_callbacks(ti->table, &pt->callbacks);
 
index 4574e0d..70a1063 100644 (file)
@@ -727,7 +727,7 @@ static int dmz_get_zoned_device(struct dm_target *ti, char *path)
        dev->zone_nr_blocks = dmz_sect2blk(dev->zone_nr_sectors);
        dev->zone_nr_blocks_shift = ilog2(dev->zone_nr_blocks);
 
-       dev->nr_zones = blkdev_nr_zones(dev->bdev);
+       dev->nr_zones = blkdev_nr_zones(dev->bdev->bd_disk);
 
        dmz->dev = dev;
 
index 805b33e..4e7c9f3 100644 (file)
@@ -1159,6 +1159,7 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
        /* not spare disk, or LEVEL_MULTIPATH */
        if (sb->level == LEVEL_MULTIPATH ||
                (rdev->desc_nr >= 0 &&
+                rdev->desc_nr < MD_SB_DISKS &&
                 sb->disks[rdev->desc_nr].state &
                 ((1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE))))
                spare_disk = false;
index 21ea537..eff04fa 100644 (file)
@@ -203,7 +203,13 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
        struct btree_node *right = r->n;
        uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
        uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
-       unsigned threshold = 2 * merge_threshold(left) + 1;
+       /*
+        * Ensure the number of entries in each child will be greater
+        * than or equal to (max_entries / 3 + 1), so no matter which
+        * child is used for removal, the number will still be not
+        * less than (max_entries / 3).
+        */
+       unsigned int threshold = 2 * (merge_threshold(left) + 1);
 
        if (nr_left + nr_right < threshold) {
                /*
index a409ab6..201fd8a 100644 (file)
@@ -2782,7 +2782,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
                                write_targets++;
                        }
                }
-               if (bio->bi_end_io) {
+               if (rdev && bio->bi_end_io) {
                        atomic_inc(&rdev->nr_pending);
                        bio->bi_iter.bi_sector = sector_nr + rdev->data_offset;
                        bio_set_dev(bio, rdev->bdev);
index cab5b13..d50238d 100644 (file)
@@ -1360,7 +1360,7 @@ int ppl_init_log(struct r5conf *conf)
                return -EINVAL;
        }
 
-       max_disks = FIELD_SIZEOF(struct ppl_log, disk_flush_bitmap) *
+       max_disks = sizeof_field(struct ppl_log, disk_flush_bitmap) *
                BITS_PER_BYTE;
        if (conf->raid_disks > max_disks) {
                pr_warn("md/raid:%s PPL doesn't support over %d disks in the array\n",
index f0fc538..d4d3b67 100644 (file)
@@ -5726,7 +5726,7 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
                                do_flush = false;
                        }
 
-                       if (!sh->batch_head)
+                       if (!sh->batch_head || sh == sh->batch_head)
                                set_bit(STRIPE_HANDLE, &sh->state);
                        clear_bit(STRIPE_DELAYED, &sh->state);
                        if ((!sh->batch_head || sh == sh->batch_head) &&
index 97d6606..4dbdf31 100644 (file)
@@ -753,7 +753,7 @@ static const struct preview_update update_attrs[] = {
                preview_config_luma_enhancement,
                preview_enable_luma_enhancement,
                offsetof(struct prev_params, luma),
-               FIELD_SIZEOF(struct prev_params, luma),
+               sizeof_field(struct prev_params, luma),
                offsetof(struct omap3isp_prev_update_config, luma),
        }, /* OMAP3ISP_PREV_INVALAW */ {
                NULL,
@@ -762,55 +762,55 @@ static const struct preview_update update_attrs[] = {
                preview_config_hmed,
                preview_enable_hmed,
                offsetof(struct prev_params, hmed),
-               FIELD_SIZEOF(struct prev_params, hmed),
+               sizeof_field(struct prev_params, hmed),
                offsetof(struct omap3isp_prev_update_config, hmed),
        }, /* OMAP3ISP_PREV_CFA */ {
                preview_config_cfa,
                NULL,
                offsetof(struct prev_params, cfa),
-               FIELD_SIZEOF(struct prev_params, cfa),
+               sizeof_field(struct prev_params, cfa),
                offsetof(struct omap3isp_prev_update_config, cfa),
        }, /* OMAP3ISP_PREV_CHROMA_SUPP */ {
                preview_config_chroma_suppression,
                preview_enable_chroma_suppression,
                offsetof(struct prev_params, csup),
-               FIELD_SIZEOF(struct prev_params, csup),
+               sizeof_field(struct prev_params, csup),
                offsetof(struct omap3isp_prev_update_config, csup),
        }, /* OMAP3ISP_PREV_WB */ {
                preview_config_whitebalance,
                NULL,
                offsetof(struct prev_params, wbal),
-               FIELD_SIZEOF(struct prev_params, wbal),
+               sizeof_field(struct prev_params, wbal),
                offsetof(struct omap3isp_prev_update_config, wbal),
        }, /* OMAP3ISP_PREV_BLKADJ */ {
                preview_config_blkadj,
                NULL,
                offsetof(struct prev_params, blkadj),
-               FIELD_SIZEOF(struct prev_params, blkadj),
+               sizeof_field(struct prev_params, blkadj),
                offsetof(struct omap3isp_prev_update_config, blkadj),
        }, /* OMAP3ISP_PREV_RGB2RGB */ {
                preview_config_rgb_blending,
                NULL,
                offsetof(struct prev_params, rgb2rgb),
-               FIELD_SIZEOF(struct prev_params, rgb2rgb),
+               sizeof_field(struct prev_params, rgb2rgb),
                offsetof(struct omap3isp_prev_update_config, rgb2rgb),
        }, /* OMAP3ISP_PREV_COLOR_CONV */ {
                preview_config_csc,
                NULL,
                offsetof(struct prev_params, csc),
-               FIELD_SIZEOF(struct prev_params, csc),
+               sizeof_field(struct prev_params, csc),
                offsetof(struct omap3isp_prev_update_config, csc),
        }, /* OMAP3ISP_PREV_YC_LIMIT */ {
                preview_config_yc_range,
                NULL,
                offsetof(struct prev_params, yclimit),
-               FIELD_SIZEOF(struct prev_params, yclimit),
+               sizeof_field(struct prev_params, yclimit),
                offsetof(struct omap3isp_prev_update_config, yclimit),
        }, /* OMAP3ISP_PREV_DEFECT_COR */ {
                preview_config_dcor,
                preview_enable_dcor,
                offsetof(struct prev_params, dcor),
-               FIELD_SIZEOF(struct prev_params, dcor),
+               sizeof_field(struct prev_params, dcor),
                offsetof(struct omap3isp_prev_update_config, dcor),
        }, /* Previously OMAP3ISP_PREV_GAMMABYPASS, not used anymore */ {
                NULL,
@@ -828,13 +828,13 @@ static const struct preview_update update_attrs[] = {
                preview_config_noisefilter,
                preview_enable_noisefilter,
                offsetof(struct prev_params, nf),
-               FIELD_SIZEOF(struct prev_params, nf),
+               sizeof_field(struct prev_params, nf),
                offsetof(struct omap3isp_prev_update_config, nf),
        }, /* OMAP3ISP_PREV_GAMMA */ {
                preview_config_gammacorrn,
                preview_enable_gammacorrn,
                offsetof(struct prev_params, gamma),
-               FIELD_SIZEOF(struct prev_params, gamma),
+               sizeof_field(struct prev_params, gamma),
                offsetof(struct omap3isp_prev_update_config, gamma),
        }, /* OMAP3ISP_PREV_CONTRAST */ {
                preview_config_contrast,
index 4e70058..003b742 100644 (file)
@@ -2652,7 +2652,7 @@ struct v4l2_ioctl_info {
 /* Zero struct from after the field to the end */
 #define INFO_FL_CLEAR(v4l2_struct, field)                      \
        ((offsetof(struct v4l2_struct, field) +                 \
-         FIELD_SIZEOF(struct v4l2_struct, field)) << 16)
+         sizeof_field(struct v4l2_struct, field)) << 16)
 #define INFO_FL_CLEAR_MASK     (_IOC_SIZEMASK << 16)
 
 #define DEFINE_V4L_STUB_FUNC(_vidioc)                          \
index 0322df9..14386d0 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * EBI driver for Atmel chips
  * inspired by the fsl weim bus driver
  *
  * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/clk.h>
@@ -19,6 +16,8 @@
 #include <linux/regmap.h>
 #include <soc/at91/atmel-sfr.h>
 
+#define AT91_EBI_NUM_CS                8
+
 struct atmel_ebi_dev_config {
        int cs;
        struct atmel_smc_cs_conf smcconf;
@@ -314,7 +313,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
                if (ret)
                        return ret;
 
-               if (cs >= AT91_MATRIX_EBI_NUM_CS ||
+               if (cs >= AT91_EBI_NUM_CS ||
                    !(ebi->caps->available_cs & BIT(cs))) {
                        dev_err(dev, "invalid reg property in %pOF\n", np);
                        return -EINVAL;
@@ -344,7 +343,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
                apply = true;
 
        i = 0;
-       for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) {
+       for_each_set_bit(cs, &cslines, AT91_EBI_NUM_CS) {
                ebid->configs[i].cs = cs;
 
                if (apply) {
index 6827ed4..82b415b 100644 (file)
@@ -127,7 +127,6 @@ enum dpfe_msg_fields {
        MSG_COMMAND,
        MSG_ARG_COUNT,
        MSG_ARG0,
-       MSG_CHKSUM,
        MSG_FIELD_MAX   = 16 /* Max number of arguments */
 };
 
@@ -180,7 +179,7 @@ struct dpfe_api {
 };
 
 /* Things we need for as long as we are active. */
-struct private_data {
+struct brcmstb_dpfe_priv {
        void __iomem *regs;
        void __iomem *dmem;
        void __iomem *imem;
@@ -232,9 +231,13 @@ static struct attribute *dpfe_v3_attrs[] = {
 };
 ATTRIBUTE_GROUPS(dpfe_v3);
 
-/* API v2 firmware commands */
-static const struct dpfe_api dpfe_api_v2 = {
-       .version = 2,
+/*
+ * Old API v2 firmware commands, as defined in the rev 0.61 specification, we
+ * use a version set to 1 to denote that it is not compatible with the new API
+ * v2 and onwards.
+ */
+static const struct dpfe_api dpfe_api_old_v2 = {
+       .version = 1,
        .fw_name = "dpfe.bin",
        .sysfs_attrs = dpfe_v2_groups,
        .command = {
@@ -243,21 +246,42 @@ static const struct dpfe_api dpfe_api_v2 = {
                        [MSG_COMMAND] = 1,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 1,
-                       [MSG_CHKSUM] = 4,
                },
                [DPFE_CMD_GET_REFRESH] = {
                        [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
                        [MSG_COMMAND] = 2,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 1,
-                       [MSG_CHKSUM] = 5,
                },
                [DPFE_CMD_GET_VENDOR] = {
                        [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
                        [MSG_COMMAND] = 2,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 2,
-                       [MSG_CHKSUM] = 6,
+               },
+       }
+};
+
+/*
+ * API v2 firmware commands, as defined in the rev 0.8 specification, named new
+ * v2 here
+ */
+static const struct dpfe_api dpfe_api_new_v2 = {
+       .version = 2,
+       .fw_name = NULL, /* We expect the firmware to have been downloaded! */
+       .sysfs_attrs = dpfe_v2_groups,
+       .command = {
+               [DPFE_CMD_GET_INFO] = {
+                       [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
+                       [MSG_COMMAND] = 0x101,
+               },
+               [DPFE_CMD_GET_REFRESH] = {
+                       [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
+                       [MSG_COMMAND] = 0x201,
+               },
+               [DPFE_CMD_GET_VENDOR] = {
+                       [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
+                       [MSG_COMMAND] = 0x202,
                },
        }
 };
@@ -273,49 +297,51 @@ static const struct dpfe_api dpfe_api_v3 = {
                        [MSG_COMMAND] = 0x0101,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 1,
-                       [MSG_CHKSUM] = 0x104,
                },
                [DPFE_CMD_GET_REFRESH] = {
                        [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
                        [MSG_COMMAND] = 0x0202,
                        [MSG_ARG_COUNT] = 0,
-                       /*
-                        * This is a bit ugly. Without arguments, the checksum
-                        * follows right after the argument count and not at
-                        * offset MSG_CHKSUM.
-                        */
-                       [MSG_ARG0] = 0x203,
                },
                /* There's no GET_VENDOR command in API v3. */
        },
 };
 
-static bool is_dcpu_enabled(void __iomem *regs)
+static bool is_dcpu_enabled(struct brcmstb_dpfe_priv *priv)
 {
        u32 val;
 
-       val = readl_relaxed(regs + REG_DCPU_RESET);
+       mutex_lock(&priv->lock);
+       val = readl_relaxed(priv->regs + REG_DCPU_RESET);
+       mutex_unlock(&priv->lock);
 
        return !(val & DCPU_RESET_MASK);
 }
 
-static void __disable_dcpu(void __iomem *regs)
+static void __disable_dcpu(struct brcmstb_dpfe_priv *priv)
 {
        u32 val;
 
-       if (!is_dcpu_enabled(regs))
+       if (!is_dcpu_enabled(priv))
                return;
 
+       mutex_lock(&priv->lock);
+
        /* Put DCPU in reset if it's running. */
-       val = readl_relaxed(regs + REG_DCPU_RESET);
+       val = readl_relaxed(priv->regs + REG_DCPU_RESET);
        val |= (1 << DCPU_RESET_SHIFT);
-       writel_relaxed(val, regs + REG_DCPU_RESET);
+       writel_relaxed(val, priv->regs + REG_DCPU_RESET);
+
+       mutex_unlock(&priv->lock);
 }
 
-static void __enable_dcpu(void __iomem *regs)
+static void __enable_dcpu(struct brcmstb_dpfe_priv *priv)
 {
+       void __iomem *regs = priv->regs;
        u32 val;
 
+       mutex_lock(&priv->lock);
+
        /* Clear mailbox registers. */
        writel_relaxed(0, regs + REG_TO_DCPU_MBOX);
        writel_relaxed(0, regs + REG_TO_HOST_MBOX);
@@ -329,6 +355,8 @@ static void __enable_dcpu(void __iomem *regs)
        val = readl_relaxed(regs + REG_DCPU_RESET);
        val &= ~(1 << DCPU_RESET_SHIFT);
        writel_relaxed(val, regs + REG_DCPU_RESET);
+
+       mutex_unlock(&priv->lock);
 }
 
 static unsigned int get_msg_chksum(const u32 msg[], unsigned int max)
@@ -343,7 +371,7 @@ static unsigned int get_msg_chksum(const u32 msg[], unsigned int max)
        return sum;
 }
 
-static void __iomem *get_msg_ptr(struct private_data *priv, u32 response,
+static void __iomem *get_msg_ptr(struct brcmstb_dpfe_priv *priv, u32 response,
                                 char *buf, ssize_t *size)
 {
        unsigned int msg_type;
@@ -382,7 +410,7 @@ static void __iomem *get_msg_ptr(struct private_data *priv, u32 response,
        return ptr;
 }
 
-static void __finalize_command(struct private_data *priv)
+static void __finalize_command(struct brcmstb_dpfe_priv *priv)
 {
        unsigned int release_mbox;
 
@@ -390,12 +418,12 @@ static void __finalize_command(struct private_data *priv)
         * It depends on the API version which MBOX register we have to write to
         * to signal we are done.
         */
-       release_mbox = (priv->dpfe_api->version < 3)
+       release_mbox = (priv->dpfe_api->version < 2)
                        ? REG_TO_HOST_MBOX : REG_TO_DCPU_MBOX;
        writel_relaxed(0, priv->regs + release_mbox);
 }
 
-static int __send_command(struct private_data *priv, unsigned int cmd,
+static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd,
                          u32 result[])
 {
        const u32 *msg = priv->dpfe_api->command[cmd];
@@ -421,9 +449,17 @@ static int __send_command(struct private_data *priv, unsigned int cmd,
                return -ETIMEDOUT;
        }
 
+       /* Compute checksum over the message */
+       chksum_idx = msg[MSG_ARG_COUNT] + MSG_ARG_COUNT + 1;
+       chksum = get_msg_chksum(msg, chksum_idx);
+
        /* Write command and arguments to message area */
-       for (i = 0; i < MSG_FIELD_MAX; i++)
-               writel_relaxed(msg[i], regs + DCPU_MSG_RAM(i));
+       for (i = 0; i < MSG_FIELD_MAX; i++) {
+               if (i == chksum_idx)
+                       writel_relaxed(chksum, regs + DCPU_MSG_RAM(i));
+               else
+                       writel_relaxed(msg[i], regs + DCPU_MSG_RAM(i));
+       }
 
        /* Tell DCPU there is a command waiting */
        writel_relaxed(1, regs + REG_TO_DCPU_MBOX);
@@ -517,7 +553,7 @@ static int __verify_firmware(struct init_data *init,
 
 /* Verify checksum by reading back the firmware from co-processor RAM. */
 static int __verify_fw_checksum(struct init_data *init,
-                               struct private_data *priv,
+                               struct brcmstb_dpfe_priv *priv,
                                const struct dpfe_firmware_header *header,
                                u32 checksum)
 {
@@ -571,26 +607,23 @@ static int __write_firmware(u32 __iomem *mem, const u32 *fw,
        return 0;
 }
 
-static int brcmstb_dpfe_download_firmware(struct platform_device *pdev,
-                                         struct init_data *init)
+static int brcmstb_dpfe_download_firmware(struct brcmstb_dpfe_priv *priv)
 {
        const struct dpfe_firmware_header *header;
        unsigned int dmem_size, imem_size;
-       struct device *dev = &pdev->dev;
+       struct device *dev = priv->dev;
        bool is_big_endian = false;
-       struct private_data *priv;
        const struct firmware *fw;
        const u32 *dmem, *imem;
+       struct init_data init;
        const void *fw_blob;
        int ret;
 
-       priv = platform_get_drvdata(pdev);
-
        /*
         * Skip downloading the firmware if the DCPU is already running and
         * responding to commands.
         */
-       if (is_dcpu_enabled(priv->regs)) {
+       if (is_dcpu_enabled(priv)) {
                u32 response[MSG_FIELD_MAX];
 
                ret = __send_command(priv, DPFE_CMD_GET_INFO, response);
@@ -606,20 +639,23 @@ static int brcmstb_dpfe_download_firmware(struct platform_device *pdev,
        if (!priv->dpfe_api->fw_name)
                return -ENODEV;
 
-       ret = request_firmware(&fw, priv->dpfe_api->fw_name, dev);
-       /* request_firmware() prints its own error messages. */
+       ret = firmware_request_nowarn(&fw, priv->dpfe_api->fw_name, dev);
+       /*
+        * Defer the firmware download if the firmware file couldn't be found.
+        * The root file system may not be available yet.
+        */
        if (ret)
-               return ret;
+               return (ret == -ENOENT) ? -EPROBE_DEFER : ret;
 
-       ret = __verify_firmware(init, fw);
+       ret = __verify_firmware(&init, fw);
        if (ret)
                return -EFAULT;
 
-       __disable_dcpu(priv->regs);
+       __disable_dcpu(priv);
 
-       is_big_endian = init->is_big_endian;
-       dmem_size = init->dmem_len;
-       imem_size = init->imem_len;
+       is_big_endian = init.is_big_endian;
+       dmem_size = init.dmem_len;
+       imem_size = init.imem_len;
 
        /* At the beginning of the firmware blob is a header. */
        header = (struct dpfe_firmware_header *)fw->data;
@@ -637,17 +673,17 @@ static int brcmstb_dpfe_download_firmware(struct platform_device *pdev,
        if (ret)
                return ret;
 
-       ret = __verify_fw_checksum(init, priv, header, init->chksum);
+       ret = __verify_fw_checksum(&init, priv, header, init.chksum);
        if (ret)
                return ret;
 
-       __enable_dcpu(priv->regs);
+       __enable_dcpu(priv);
 
        return 0;
 }
 
 static ssize_t generic_show(unsigned int command, u32 response[],
-                           struct private_data *priv, char *buf)
+                           struct brcmstb_dpfe_priv *priv, char *buf)
 {
        int ret;
 
@@ -665,7 +701,7 @@ static ssize_t show_info(struct device *dev, struct device_attribute *devattr,
                         char *buf)
 {
        u32 response[MSG_FIELD_MAX];
-       struct private_data *priv;
+       struct brcmstb_dpfe_priv *priv;
        unsigned int info;
        ssize_t ret;
 
@@ -688,7 +724,7 @@ static ssize_t show_refresh(struct device *dev,
 {
        u32 response[MSG_FIELD_MAX];
        void __iomem *info;
-       struct private_data *priv;
+       struct brcmstb_dpfe_priv *priv;
        u8 refresh, sr_abort, ppre, thermal_offs, tuf;
        u32 mr4;
        ssize_t ret;
@@ -721,7 +757,7 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
                          const char *buf, size_t count)
 {
        u32 response[MSG_FIELD_MAX];
-       struct private_data *priv;
+       struct brcmstb_dpfe_priv *priv;
        void __iomem *info;
        unsigned long val;
        int ret;
@@ -747,7 +783,7 @@ static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr,
                           char *buf)
 {
        u32 response[MSG_FIELD_MAX];
-       struct private_data *priv;
+       struct brcmstb_dpfe_priv *priv;
        void __iomem *info;
        ssize_t ret;
        u32 mr5, mr6, mr7, mr8, err;
@@ -778,7 +814,7 @@ static ssize_t show_dram(struct device *dev, struct device_attribute *devattr,
                         char *buf)
 {
        u32 response[MSG_FIELD_MAX];
-       struct private_data *priv;
+       struct brcmstb_dpfe_priv *priv;
        ssize_t ret;
        u32 mr4, mr5, mr6, mr7, mr8, err;
 
@@ -800,16 +836,15 @@ static ssize_t show_dram(struct device *dev, struct device_attribute *devattr,
 
 static int brcmstb_dpfe_resume(struct platform_device *pdev)
 {
-       struct init_data init;
+       struct brcmstb_dpfe_priv *priv = platform_get_drvdata(pdev);
 
-       return brcmstb_dpfe_download_firmware(pdev, &init);
+       return brcmstb_dpfe_download_firmware(priv);
 }
 
 static int brcmstb_dpfe_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct private_data *priv;
-       struct init_data init;
+       struct brcmstb_dpfe_priv *priv;
        struct resource *res;
        int ret;
 
@@ -817,6 +852,8 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
        if (!priv)
                return -ENOMEM;
 
+       priv->dev = dev;
+
        mutex_init(&priv->lock);
        platform_set_drvdata(pdev, priv);
 
@@ -851,9 +888,10 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
                return -ENOENT;
        }
 
-       ret = brcmstb_dpfe_download_firmware(pdev, &init);
+       ret = brcmstb_dpfe_download_firmware(priv);
        if (ret) {
-               dev_err(dev, "Couldn't download firmware -- %d\n", ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Couldn't download firmware -- %d\n", ret);
                return ret;
        }
 
@@ -867,7 +905,7 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
 
 static int brcmstb_dpfe_remove(struct platform_device *pdev)
 {
-       struct private_data *priv = dev_get_drvdata(&pdev->dev);
+       struct brcmstb_dpfe_priv *priv = dev_get_drvdata(&pdev->dev);
 
        sysfs_remove_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs);
 
@@ -876,10 +914,10 @@ static int brcmstb_dpfe_remove(struct platform_device *pdev)
 
 static const struct of_device_id brcmstb_dpfe_of_match[] = {
        /* Use legacy API v2 for a select number of chips */
-       { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_v2 },
-       { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_v2 },
-       { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_v2 },
-       { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_v2 },
+       { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_old_v2 },
+       { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_old_v2 },
+       { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_old_v2 },
+       { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_new_v2 },
        /* API v3 is the default going forward */
        { .compatible = "brcm,dpfe-cpu", .data = &dpfe_api_v3 },
        {}
index 402c6bc..9d9127b 100644 (file)
@@ -1613,7 +1613,7 @@ static void emif_shutdown(struct platform_device *pdev)
 static int get_emif_reg_values(struct emif_data *emif, u32 freq,
                struct emif_regs *regs)
 {
-       u32                             cs1_used, ip_rev, phy_type;
+       u32                             ip_rev, phy_type;
        u32                             cl, type;
        const struct lpddr2_timings     *timings;
        const struct lpddr2_min_tck     *min_tck;
@@ -1621,7 +1621,6 @@ static int get_emif_reg_values(struct emif_data *emif, u32 freq,
        const struct lpddr2_addressing  *addressing;
        struct emif_data                *emif_for_calc;
        struct device                   *dev;
-       const struct emif_custom_configs *custom_configs;
 
        dev = emif->dev;
        /*
@@ -1639,12 +1638,10 @@ static int get_emif_reg_values(struct emif_data *emif, u32 freq,
 
        device_info     = emif_for_calc->plat_data->device_info;
        type            = device_info->type;
-       cs1_used        = device_info->cs1_used;
        ip_rev          = emif_for_calc->plat_data->ip_rev;
        phy_type        = emif_for_calc->plat_data->phy_type;
 
        min_tck         = emif_for_calc->plat_data->min_tck;
-       custom_configs  = emif_for_calc->plat_data->custom_configs;
 
        set_ddr_clk_period(freq);
 
index 4a21b50..e59ccbd 100644 (file)
@@ -29,6 +29,7 @@
 #define DDR_TYPE_LPDDR2_S4     3
 #define DDR_TYPE_LPDDR2_S2     4
 #define DDR_TYPE_LPDDR2_NVM    5
+#define DDR_TYPE_LPDDR3                6
 
 /* DDR IO width */
 #define DDR_IO_WIDTH_4         1
@@ -169,4 +170,64 @@ extern const struct lpddr2_timings
        lpddr2_jedec_timings[NUM_DDR_TIMING_TABLE_ENTRIES];
 extern const struct lpddr2_min_tck lpddr2_jedec_min_tck;
 
+/*
+ * Structure for timings for LPDDR3 based on LPDDR2 plus additional fields.
+ * All parameters are in pico seconds(ps) excluding max_freq, min_freq which
+ * are in Hz.
+ */
+struct lpddr3_timings {
+       u32 max_freq;
+       u32 min_freq;
+       u32 tRFC;
+       u32 tRRD;
+       u32 tRPab;
+       u32 tRPpb;
+       u32 tRCD;
+       u32 tRC;
+       u32 tRAS;
+       u32 tWTR;
+       u32 tWR;
+       u32 tRTP;
+       u32 tW2W_C2C;
+       u32 tR2R_C2C;
+       u32 tWL;
+       u32 tDQSCK;
+       u32 tRL;
+       u32 tFAW;
+       u32 tXSR;
+       u32 tXP;
+       u32 tCKE;
+       u32 tCKESR;
+       u32 tMRD;
+};
+
+/*
+ * Min value for some parameters in terms of number of tCK cycles(nCK)
+ * Please set to zero parameters that are not valid for a given memory
+ * type
+ */
+struct lpddr3_min_tck {
+       u32 tRFC;
+       u32 tRRD;
+       u32 tRPab;
+       u32 tRPpb;
+       u32 tRCD;
+       u32 tRC;
+       u32 tRAS;
+       u32 tWTR;
+       u32 tWR;
+       u32 tRTP;
+       u32 tW2W_C2C;
+       u32 tR2R_C2C;
+       u32 tWL;
+       u32 tDQSCK;
+       u32 tRL;
+       u32 tFAW;
+       u32 tXSR;
+       u32 tXP;
+       u32 tCKE;
+       u32 tCKESR;
+       u32 tMRD;
+};
+
 #endif /* __JEDEC_DDR_H */
index 46539b2..71f26ea 100644 (file)
@@ -3,6 +3,7 @@
  * OpenFirmware helpers for memory drivers
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
+ * Copyright (C) 2019 Samsung Electronics Co., Ltd.
  */
 
 #include <linux/device.h>
@@ -149,3 +150,151 @@ default_timings:
        return lpddr2_jedec_timings;
 }
 EXPORT_SYMBOL(of_get_ddr_timings);
+
+/**
+ * of_lpddr3_get_min_tck() - extract min timing values for lpddr3
+ * @np: pointer to ddr device tree node
+ * @device: device requesting for min timing values
+ *
+ * Populates the lpddr3_min_tck structure by extracting data
+ * from device tree node. Returns a pointer to the populated
+ * structure. If any error in populating the structure, returns NULL.
+ */
+const struct lpddr3_min_tck *of_lpddr3_get_min_tck(struct device_node *np,
+                                                  struct device *dev)
+{
+       int                     ret = 0;
+       struct lpddr3_min_tck   *min;
+
+       min = devm_kzalloc(dev, sizeof(*min), GFP_KERNEL);
+       if (!min)
+               goto default_min_tck;
+
+       ret |= of_property_read_u32(np, "tRFC-min-tck", &min->tRFC);
+       ret |= of_property_read_u32(np, "tRRD-min-tck", &min->tRRD);
+       ret |= of_property_read_u32(np, "tRPab-min-tck", &min->tRPab);
+       ret |= of_property_read_u32(np, "tRPpb-min-tck", &min->tRPpb);
+       ret |= of_property_read_u32(np, "tRCD-min-tck", &min->tRCD);
+       ret |= of_property_read_u32(np, "tRC-min-tck", &min->tRC);
+       ret |= of_property_read_u32(np, "tRAS-min-tck", &min->tRAS);
+       ret |= of_property_read_u32(np, "tWTR-min-tck", &min->tWTR);
+       ret |= of_property_read_u32(np, "tWR-min-tck", &min->tWR);
+       ret |= of_property_read_u32(np, "tRTP-min-tck", &min->tRTP);
+       ret |= of_property_read_u32(np, "tW2W-C2C-min-tck", &min->tW2W_C2C);
+       ret |= of_property_read_u32(np, "tR2R-C2C-min-tck", &min->tR2R_C2C);
+       ret |= of_property_read_u32(np, "tWL-min-tck", &min->tWL);
+       ret |= of_property_read_u32(np, "tDQSCK-min-tck", &min->tDQSCK);
+       ret |= of_property_read_u32(np, "tRL-min-tck", &min->tRL);
+       ret |= of_property_read_u32(np, "tFAW-min-tck", &min->tFAW);
+       ret |= of_property_read_u32(np, "tXSR-min-tck", &min->tXSR);
+       ret |= of_property_read_u32(np, "tXP-min-tck", &min->tXP);
+       ret |= of_property_read_u32(np, "tCKE-min-tck", &min->tCKE);
+       ret |= of_property_read_u32(np, "tCKESR-min-tck", &min->tCKESR);
+       ret |= of_property_read_u32(np, "tMRD-min-tck", &min->tMRD);
+
+       if (ret) {
+               dev_warn(dev, "%s: errors while parsing min-tck values\n",
+                        __func__);
+               devm_kfree(dev, min);
+               goto default_min_tck;
+       }
+
+       return min;
+
+default_min_tck:
+       dev_warn(dev, "%s: using default min-tck values\n", __func__);
+       return NULL;
+}
+EXPORT_SYMBOL(of_lpddr3_get_min_tck);
+
+static int of_lpddr3_do_get_timings(struct device_node *np,
+                                   struct lpddr3_timings *tim)
+{
+       int ret;
+
+       /* The 'reg' param required since DT has changed, used as 'max-freq' */
+       ret = of_property_read_u32(np, "reg", &tim->max_freq);
+       ret |= of_property_read_u32(np, "min-freq", &tim->min_freq);
+       ret |= of_property_read_u32(np, "tRFC", &tim->tRFC);
+       ret |= of_property_read_u32(np, "tRRD", &tim->tRRD);
+       ret |= of_property_read_u32(np, "tRPab", &tim->tRPab);
+       ret |= of_property_read_u32(np, "tRPpb", &tim->tRPpb);
+       ret |= of_property_read_u32(np, "tRCD", &tim->tRCD);
+       ret |= of_property_read_u32(np, "tRC", &tim->tRC);
+       ret |= of_property_read_u32(np, "tRAS", &tim->tRAS);
+       ret |= of_property_read_u32(np, "tWTR", &tim->tWTR);
+       ret |= of_property_read_u32(np, "tWR", &tim->tWR);
+       ret |= of_property_read_u32(np, "tRTP", &tim->tRTP);
+       ret |= of_property_read_u32(np, "tW2W-C2C", &tim->tW2W_C2C);
+       ret |= of_property_read_u32(np, "tR2R-C2C", &tim->tR2R_C2C);
+       ret |= of_property_read_u32(np, "tFAW", &tim->tFAW);
+       ret |= of_property_read_u32(np, "tXSR", &tim->tXSR);
+       ret |= of_property_read_u32(np, "tXP", &tim->tXP);
+       ret |= of_property_read_u32(np, "tCKE", &tim->tCKE);
+       ret |= of_property_read_u32(np, "tCKESR", &tim->tCKESR);
+       ret |= of_property_read_u32(np, "tMRD", &tim->tMRD);
+
+       return ret;
+}
+
+/**
+ * of_lpddr3_get_ddr_timings() - extracts the lpddr3 timings and updates no of
+ * frequencies available.
+ * @np_ddr: Pointer to ddr device tree node
+ * @dev: Device requesting for ddr timings
+ * @device_type: Type of ddr
+ * @nr_frequencies: No of frequencies available for ddr
+ * (updated by this function)
+ *
+ * Populates lpddr3_timings structure by extracting data from device
+ * tree node. Returns pointer to populated structure. If any error
+ * while populating, returns NULL.
+ */
+const struct lpddr3_timings
+*of_lpddr3_get_ddr_timings(struct device_node *np_ddr, struct device *dev,
+                          u32 device_type, u32 *nr_frequencies)
+{
+       struct lpddr3_timings   *timings = NULL;
+       u32                     arr_sz = 0, i = 0;
+       struct device_node      *np_tim;
+       char                    *tim_compat = NULL;
+
+       switch (device_type) {
+       case DDR_TYPE_LPDDR3:
+               tim_compat = "jedec,lpddr3-timings";
+               break;
+       default:
+               dev_warn(dev, "%s: un-supported memory type\n", __func__);
+       }
+
+       for_each_child_of_node(np_ddr, np_tim)
+               if (of_device_is_compatible(np_tim, tim_compat))
+                       arr_sz++;
+
+       if (arr_sz)
+               timings = devm_kcalloc(dev, arr_sz, sizeof(*timings),
+                                      GFP_KERNEL);
+
+       if (!timings)
+               goto default_timings;
+
+       for_each_child_of_node(np_ddr, np_tim) {
+               if (of_device_is_compatible(np_tim, tim_compat)) {
+                       if (of_lpddr3_do_get_timings(np_tim, &timings[i])) {
+                               devm_kfree(dev, timings);
+                               goto default_timings;
+                       }
+                       i++;
+               }
+       }
+
+       *nr_frequencies = arr_sz;
+
+       return timings;
+
+default_timings:
+       dev_warn(dev, "%s: failed to get timings\n", __func__);
+       *nr_frequencies = 0;
+       return NULL;
+}
+EXPORT_SYMBOL(of_lpddr3_get_ddr_timings);
index b077cc8..e39ecc4 100644 (file)
@@ -14,6 +14,11 @@ extern const struct lpddr2_min_tck *of_get_min_tck(struct device_node *np,
 extern const struct lpddr2_timings
        *of_get_ddr_timings(struct device_node *np_ddr, struct device *dev,
        u32 device_type, u32 *nr_frequencies);
+extern const struct lpddr3_min_tck
+       *of_lpddr3_get_min_tck(struct device_node *np, struct device *dev);
+extern const struct lpddr3_timings
+       *of_lpddr3_get_ddr_timings(struct device_node *np_ddr,
+       struct device *dev, u32 device_type, u32 *nr_frequencies);
 #else
 static inline const struct lpddr2_min_tck
        *of_get_min_tck(struct device_node *np, struct device *dev)
@@ -27,6 +32,19 @@ static inline const struct lpddr2_timings
 {
        return NULL;
 }
+
+static inline const struct lpddr3_min_tck
+       *of_lpddr3_get_min_tck(struct device_node *np, struct device *dev)
+{
+       return NULL;
+}
+
+static inline const struct lpddr3_timings
+       *of_lpddr3_get_ddr_timings(struct device_node *np_ddr,
+       struct device *dev, u32 device_type, u32 *nr_frequencies)
+{
+       return NULL;
+}
 #endif /* CONFIG_OF && CONFIG_DDR */
 
 #endif /* __LINUX_MEMORY_OF_REG_ */
index 79ce7ea..e9c3ce9 100644 (file)
@@ -7,6 +7,19 @@ config SAMSUNG_MC
 
 if SAMSUNG_MC
 
+config EXYNOS5422_DMC
+       tristate "EXYNOS5422 Dynamic Memory Controller driver"
+       depends on ARCH_EXYNOS || (COMPILE_TEST && HAS_IOMEM)
+       select DDR
+       depends on DEVFREQ_GOV_SIMPLE_ONDEMAND
+       depends on (PM_DEVFREQ && PM_DEVFREQ_EVENT)
+       help
+         This adds driver for Exynos5422 DMC (Dynamic Memory Controller).
+         The driver provides support for Dynamic Voltage and Frequency Scaling in
+         DMC and DRAM. It also supports changing timings of DRAM running with
+         different frequency. The timings are calculated based on DT memory
+         information.
+
 config EXYNOS_SROM
        bool "Exynos SROM controller driver" if COMPILE_TEST
        depends on (ARM && ARCH_EXYNOS) || (COMPILE_TEST && HAS_IOMEM)
index 00587be..ea071be 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_EXYNOS5422_DMC)   += exynos5422-dmc.o
 obj-$(CONFIG_EXYNOS_SROM)      += exynos-srom.o
diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c
new file mode 100644 (file)
index 0000000..47dbf6d
--- /dev/null
@@ -0,0 +1,1550 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Author: Lukasz Luba <l.luba@partner.samsung.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/devfreq.h>
+#include <linux/devfreq-event.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_opp.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include "../jedec_ddr.h"
+#include "../of_memory.h"
+
+#define EXYNOS5_DREXI_TIMINGAREF               (0x0030)
+#define EXYNOS5_DREXI_TIMINGROW0               (0x0034)
+#define EXYNOS5_DREXI_TIMINGDATA0              (0x0038)
+#define EXYNOS5_DREXI_TIMINGPOWER0             (0x003C)
+#define EXYNOS5_DREXI_TIMINGROW1               (0x00E4)
+#define EXYNOS5_DREXI_TIMINGDATA1              (0x00E8)
+#define EXYNOS5_DREXI_TIMINGPOWER1             (0x00EC)
+#define CDREX_PAUSE                            (0x2091c)
+#define CDREX_LPDDR3PHY_CON3                   (0x20a20)
+#define CDREX_LPDDR3PHY_CLKM_SRC               (0x20700)
+#define EXYNOS5_TIMING_SET_SWI                 BIT(28)
+#define USE_MX_MSPLL_TIMINGS                   (1)
+#define USE_BPLL_TIMINGS                       (0)
+#define EXYNOS5_AREF_NORMAL                    (0x2e)
+
+#define DREX_PPCCLKCON         (0x0130)
+#define DREX_PEREV2CONFIG      (0x013c)
+#define DREX_PMNC_PPC          (0xE000)
+#define DREX_CNTENS_PPC                (0xE010)
+#define DREX_CNTENC_PPC                (0xE020)
+#define DREX_INTENS_PPC                (0xE030)
+#define DREX_INTENC_PPC                (0xE040)
+#define DREX_FLAG_PPC          (0xE050)
+#define DREX_PMCNT2_PPC                (0xE130)
+
+/*
+ * A value for register DREX_PMNC_PPC which should be written to reset
+ * the cycle counter CCNT (a reference wall clock). It sets zero to the
+ * CCNT counter.
+ */
+#define CC_RESET               BIT(2)
+
+/*
+ * A value for register DREX_PMNC_PPC which does the reset of all performance
+ * counters to zero.
+ */
+#define PPC_COUNTER_RESET      BIT(1)
+
+/*
+ * Enables all configured counters (including cycle counter). The value should
+ * be written to the register DREX_PMNC_PPC.
+ */
+#define PPC_ENABLE             BIT(0)
+
+/* A value for register DREX_PPCCLKCON which enables performance events clock.
+ * Must be written before first access to the performance counters register
+ * set, otherwise it could crash.
+ */
+#define PEREV_CLK_EN           BIT(0)
+
+/*
+ * Values which are used to enable counters, interrupts or configure flags of
+ * the performance counters. They configure counter 2 and cycle counter.
+ */
+#define PERF_CNT2              BIT(2)
+#define PERF_CCNT              BIT(31)
+
+/*
+ * Performance event types which are used for setting the preferred event
+ * to track in the counters.
+ * There is a set of different types, the values are from range 0 to 0x6f.
+ * These settings should be written to the configuration register which manages
+ * the type of the event (register DREX_PEREV2CONFIG).
+ */
+#define READ_TRANSFER_CH0      (0x6d)
+#define READ_TRANSFER_CH1      (0x6f)
+
+#define PERF_COUNTER_START_VALUE 0xff000000
+#define PERF_EVENT_UP_DOWN_THRESHOLD 900000000ULL
+
+/**
+ * struct dmc_opp_table - Operating level desciption
+ *
+ * Covers frequency and voltage settings of the DMC operating mode.
+ */
+struct dmc_opp_table {
+       u32 freq_hz;
+       u32 volt_uv;
+};
+
+/**
+ * struct exynos5_dmc - main structure describing DMC device
+ *
+ * The main structure for the Dynamic Memory Controller which covers clocks,
+ * memory regions, HW information, parameters and current operating mode.
+ */
+struct exynos5_dmc {
+       struct device *dev;
+       struct devfreq *df;
+       struct devfreq_simple_ondemand_data gov_data;
+       void __iomem *base_drexi0;
+       void __iomem *base_drexi1;
+       struct regmap *clk_regmap;
+       struct mutex lock;
+       unsigned long curr_rate;
+       unsigned long curr_volt;
+       unsigned long bypass_rate;
+       struct dmc_opp_table *opp;
+       struct dmc_opp_table opp_bypass;
+       int opp_count;
+       u32 timings_arr_size;
+       u32 *timing_row;
+       u32 *timing_data;
+       u32 *timing_power;
+       const struct lpddr3_timings *timings;
+       const struct lpddr3_min_tck *min_tck;
+       u32 bypass_timing_row;
+       u32 bypass_timing_data;
+       u32 bypass_timing_power;
+       struct regulator *vdd_mif;
+       struct clk *fout_spll;
+       struct clk *fout_bpll;
+       struct clk *mout_spll;
+       struct clk *mout_bpll;
+       struct clk *mout_mclk_cdrex;
+       struct clk *mout_mx_mspll_ccore;
+       struct clk *mx_mspll_ccore_phy;
+       struct clk *mout_mx_mspll_ccore_phy;
+       struct devfreq_event_dev **counter;
+       int num_counters;
+       u64 last_overflow_ts[2];
+       unsigned long load;
+       unsigned long total;
+       bool in_irq_mode;
+};
+
+#define TIMING_FIELD(t_name, t_bit_beg, t_bit_end) \
+       { .name = t_name, .bit_beg = t_bit_beg, .bit_end = t_bit_end }
+
+#define TIMING_VAL2REG(timing, t_val)                  \
+({                                                     \
+               u32 __val;                              \
+               __val = (t_val) << (timing)->bit_beg;   \
+               __val;                                  \
+})
+
+struct timing_reg {
+       char *name;
+       int bit_beg;
+       int bit_end;
+       unsigned int val;
+};
+
+static const struct timing_reg timing_row[] = {
+       TIMING_FIELD("tRFC", 24, 31),
+       TIMING_FIELD("tRRD", 20, 23),
+       TIMING_FIELD("tRP", 16, 19),
+       TIMING_FIELD("tRCD", 12, 15),
+       TIMING_FIELD("tRC", 6, 11),
+       TIMING_FIELD("tRAS", 0, 5),
+};
+
+static const struct timing_reg timing_data[] = {
+       TIMING_FIELD("tWTR", 28, 31),
+       TIMING_FIELD("tWR", 24, 27),
+       TIMING_FIELD("tRTP", 20, 23),
+       TIMING_FIELD("tW2W-C2C", 14, 14),
+       TIMING_FIELD("tR2R-C2C", 12, 12),
+       TIMING_FIELD("WL", 8, 11),
+       TIMING_FIELD("tDQSCK", 4, 7),
+       TIMING_FIELD("RL", 0, 3),
+};
+
+static const struct timing_reg timing_power[] = {
+       TIMING_FIELD("tFAW", 26, 31),
+       TIMING_FIELD("tXSR", 16, 25),
+       TIMING_FIELD("tXP", 8, 15),
+       TIMING_FIELD("tCKE", 4, 7),
+       TIMING_FIELD("tMRD", 0, 3),
+};
+
+#define TIMING_COUNT (ARRAY_SIZE(timing_row) + ARRAY_SIZE(timing_data) + \
+                     ARRAY_SIZE(timing_power))
+
+static int exynos5_counters_set_event(struct exynos5_dmc *dmc)
+{
+       int i, ret;
+
+       for (i = 0; i < dmc->num_counters; i++) {
+               if (!dmc->counter[i])
+                       continue;
+               ret = devfreq_event_set_event(dmc->counter[i]);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+}
+
+static int exynos5_counters_enable_edev(struct exynos5_dmc *dmc)
+{
+       int i, ret;
+
+       for (i = 0; i < dmc->num_counters; i++) {
+               if (!dmc->counter[i])
+                       continue;
+               ret = devfreq_event_enable_edev(dmc->counter[i]);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+}
+
+static int exynos5_counters_disable_edev(struct exynos5_dmc *dmc)
+{
+       int i, ret;
+
+       for (i = 0; i < dmc->num_counters; i++) {
+               if (!dmc->counter[i])
+                       continue;
+               ret = devfreq_event_disable_edev(dmc->counter[i]);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+}
+
+/**
+ * find_target_freq_id() - Finds requested frequency in local DMC configuration
+ * @dmc:       device for which the information is checked
+ * @target_rate:       requested frequency in KHz
+ *
+ * Seeks in the local DMC driver structure for the requested frequency value
+ * and returns index or error value.
+ */
+static int find_target_freq_idx(struct exynos5_dmc *dmc,
+                               unsigned long target_rate)
+{
+       int i;
+
+       for (i = dmc->opp_count - 1; i >= 0; i--)
+               if (dmc->opp[i].freq_hz <= target_rate)
+                       return i;
+
+       return -EINVAL;
+}
+
+/**
+ * exynos5_switch_timing_regs() - Changes bank register set for DRAM timings
+ * @dmc:       device for which the new settings is going to be applied
+ * @set:       boolean variable passing set value
+ *
+ * Changes the register set, which holds timing parameters.
+ * There is two register sets: 0 and 1. The register set 0
+ * is used in normal operation when the clock is provided from main PLL.
+ * The bank register set 1 is used when the main PLL frequency is going to be
+ * changed and the clock is taken from alternative, stable source.
+ * This function switches between these banks according to the
+ * currently used clock source.
+ */
+static void exynos5_switch_timing_regs(struct exynos5_dmc *dmc, bool set)
+{
+       unsigned int reg;
+       int ret;
+
+       ret = regmap_read(dmc->clk_regmap, CDREX_LPDDR3PHY_CON3, &reg);
+
+       if (set)
+               reg |= EXYNOS5_TIMING_SET_SWI;
+       else
+               reg &= ~EXYNOS5_TIMING_SET_SWI;
+
+       regmap_write(dmc->clk_regmap, CDREX_LPDDR3PHY_CON3, reg);
+}
+
+/**
+ * exynos5_init_freq_table() - Initialized PM OPP framework
+ * @dmc:       DMC device for which the frequencies are used for OPP init
+ * @profile:   devfreq device's profile
+ *
+ * Populate the devfreq device's OPP table based on current frequency, voltage.
+ */
+static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
+                                  struct devfreq_dev_profile *profile)
+{
+       int i, ret;
+       int idx;
+       unsigned long freq;
+
+       ret = dev_pm_opp_of_add_table(dmc->dev);
+       if (ret < 0) {
+               dev_err(dmc->dev, "Failed to get OPP table\n");
+               return ret;
+       }
+
+       dmc->opp_count = dev_pm_opp_get_opp_count(dmc->dev);
+
+       dmc->opp = devm_kmalloc_array(dmc->dev, dmc->opp_count,
+                                     sizeof(struct dmc_opp_table), GFP_KERNEL);
+       if (!dmc->opp)
+               goto err_opp;
+
+       idx = dmc->opp_count - 1;
+       for (i = 0, freq = ULONG_MAX; i < dmc->opp_count; i++, freq--) {
+               struct dev_pm_opp *opp;
+
+               opp = dev_pm_opp_find_freq_floor(dmc->dev, &freq);
+               if (IS_ERR(opp))
+                       goto err_opp;
+
+               dmc->opp[idx - i].freq_hz = freq;
+               dmc->opp[idx - i].volt_uv = dev_pm_opp_get_voltage(opp);
+
+               dev_pm_opp_put(opp);
+       }
+
+       return 0;
+
+err_opp:
+       dev_pm_opp_of_remove_table(dmc->dev);
+
+       return -EINVAL;
+}
+
+/**
+ * exynos5_set_bypass_dram_timings() - Low-level changes of the DRAM timings
+ * @dmc:       device for which the new settings is going to be applied
+ * @param:     DRAM parameters which passes timing data
+ *
+ * Low-level function for changing timings for DRAM memory clocking from
+ * 'bypass' clock source (fixed frequency @400MHz).
+ * It uses timing bank registers set 1.
+ */
+static void exynos5_set_bypass_dram_timings(struct exynos5_dmc *dmc)
+{
+       writel(EXYNOS5_AREF_NORMAL,
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGAREF);
+
+       writel(dmc->bypass_timing_row,
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGROW1);
+       writel(dmc->bypass_timing_row,
+              dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGROW1);
+       writel(dmc->bypass_timing_data,
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGDATA1);
+       writel(dmc->bypass_timing_data,
+              dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGDATA1);
+       writel(dmc->bypass_timing_power,
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGPOWER1);
+       writel(dmc->bypass_timing_power,
+              dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGPOWER1);
+}
+
+/**
+ * exynos5_dram_change_timings() - Low-level changes of the DRAM final timings
+ * @dmc:       device for which the new settings is going to be applied
+ * @target_rate:       target frequency of the DMC
+ *
+ * Low-level function for changing timings for DRAM memory operating from main
+ * clock source (BPLL), which can have different frequencies. Thus, each
+ * frequency must have corresponding timings register values in order to keep
+ * the needed delays.
+ * It uses timing bank registers set 0.
+ */
+static int exynos5_dram_change_timings(struct exynos5_dmc *dmc,
+                                      unsigned long target_rate)
+{
+       int idx;
+
+       for (idx = dmc->opp_count - 1; idx >= 0; idx--)
+               if (dmc->opp[idx].freq_hz <= target_rate)
+                       break;
+
+       if (idx < 0)
+               return -EINVAL;
+
+       writel(EXYNOS5_AREF_NORMAL,
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGAREF);
+
+       writel(dmc->timing_row[idx],
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGROW0);
+       writel(dmc->timing_row[idx],
+              dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGROW0);
+       writel(dmc->timing_data[idx],
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGDATA0);
+       writel(dmc->timing_data[idx],
+              dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGDATA0);
+       writel(dmc->timing_power[idx],
+              dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGPOWER0);
+       writel(dmc->timing_power[idx],
+              dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGPOWER0);
+
+       return 0;
+}
+
+/**
+ * exynos5_dmc_align_target_voltage() - Sets the final voltage for the DMC
+ * @dmc:       device for which it is going to be set
+ * @target_volt:       new voltage which is chosen to be final
+ *
+ * Function tries to align voltage to the safe level for 'normal' mode.
+ * It checks the need of higher voltage and changes the value. The target
+ * voltage might be lower that currently set and still the system will be
+ * stable.
+ */
+static int exynos5_dmc_align_target_voltage(struct exynos5_dmc *dmc,
+                                           unsigned long target_volt)
+{
+       int ret = 0;
+
+       if (dmc->curr_volt <= target_volt)
+               return 0;
+
+       ret = regulator_set_voltage(dmc->vdd_mif, target_volt,
+                                   target_volt);
+       if (!ret)
+               dmc->curr_volt = target_volt;
+
+       return ret;
+}
+
+/**
+ * exynos5_dmc_align_bypass_voltage() - Sets the voltage for the DMC
+ * @dmc:       device for which it is going to be set
+ * @target_volt:       new voltage which is chosen to be final
+ *
+ * Function tries to align voltage to the safe level for the 'bypass' mode.
+ * It checks the need of higher voltage and changes the value.
+ * The target voltage must not be less than currently needed, because
+ * for current frequency the device might become unstable.
+ */
+static int exynos5_dmc_align_bypass_voltage(struct exynos5_dmc *dmc,
+                                           unsigned long target_volt)
+{
+       int ret = 0;
+       unsigned long bypass_volt = dmc->opp_bypass.volt_uv;
+
+       target_volt = max(bypass_volt, target_volt);
+
+       if (dmc->curr_volt >= target_volt)
+               return 0;
+
+       ret = regulator_set_voltage(dmc->vdd_mif, target_volt,
+                                   target_volt);
+       if (!ret)
+               dmc->curr_volt = target_volt;
+
+       return ret;
+}
+
+/**
+ * exynos5_dmc_align_bypass_dram_timings() - Chooses and sets DRAM timings
+ * @dmc:       device for which it is going to be set
+ * @target_rate:       new frequency which is chosen to be final
+ *
+ * Function changes the DRAM timings for the temporary 'bypass' mode.
+ */
+static int exynos5_dmc_align_bypass_dram_timings(struct exynos5_dmc *dmc,
+                                                unsigned long target_rate)
+{
+       int idx = find_target_freq_idx(dmc, target_rate);
+
+       if (idx < 0)
+               return -EINVAL;
+
+       exynos5_set_bypass_dram_timings(dmc);
+
+       return 0;
+}
+
+/**
+ * exynos5_dmc_switch_to_bypass_configuration() - Switching to temporary clock
+ * @dmc:       DMC device for which the switching is going to happen
+ * @target_rate:       new frequency which is going to be set as a final
+ * @target_volt:       new voltage which is going to be set as a final
+ *
+ * Function configures DMC and clocks for operating in temporary 'bypass' mode.
+ * This mode is used only temporary but if required, changes voltage and timings
+ * for DRAM chips. It switches the main clock to stable clock source for the
+ * period of the main PLL reconfiguration.
+ */
+static int
+exynos5_dmc_switch_to_bypass_configuration(struct exynos5_dmc *dmc,
+                                          unsigned long target_rate,
+                                          unsigned long target_volt)
+{
+       int ret;
+
+       /*
+        * Having higher voltage for a particular frequency does not harm
+        * the chip. Use it for the temporary frequency change when one
+        * voltage manipulation might be avoided.
+        */
+       ret = exynos5_dmc_align_bypass_voltage(dmc, target_volt);
+       if (ret)
+               return ret;
+
+       /*
+        * Longer delays for DRAM does not cause crash, the opposite does.
+        */
+       ret = exynos5_dmc_align_bypass_dram_timings(dmc, target_rate);
+       if (ret)
+               return ret;
+
+       /*
+        * Delays are long enough, so use them for the new coming clock.
+        */
+       exynos5_switch_timing_regs(dmc, USE_MX_MSPLL_TIMINGS);
+
+       return ret;
+}
+
+/**
+ * exynos5_dmc_change_freq_and_volt() - Changes voltage and frequency of the DMC
+ * using safe procedure
+ * @dmc:       device for which the frequency is going to be changed
+ * @target_rate:       requested new frequency
+ * @target_volt:       requested voltage which corresponds to the new frequency
+ *
+ * The DMC frequency change procedure requires a few steps.
+ * The main requirement is to change the clock source in the clk mux
+ * for the time of main clock PLL locking. The assumption is that the
+ * alternative clock source set as parent is stable.
+ * The second parent's clock frequency is fixed to 400MHz, it is named 'bypass'
+ * clock. This requires alignment in DRAM timing parameters for the new
+ * T-period. There is two bank sets for keeping DRAM
+ * timings: set 0 and set 1. The set 0 is used when main clock source is
+ * chosen. The 2nd set of regs is used for 'bypass' clock. Switching between
+ * the two bank sets is part of the process.
+ * The voltage must also be aligned to the minimum required level. There is
+ * this intermediate step with switching to 'bypass' parent clock source.
+ * if the old voltage is lower, it requires an increase of the voltage level.
+ * The complexity of the voltage manipulation is hidden in low level function.
+ * In this function there is last alignment of the voltage level at the end.
+ */
+static int
+exynos5_dmc_change_freq_and_volt(struct exynos5_dmc *dmc,
+                                unsigned long target_rate,
+                                unsigned long target_volt)
+{
+       int ret;
+
+       ret = exynos5_dmc_switch_to_bypass_configuration(dmc, target_rate,
+                                                        target_volt);
+       if (ret)
+               return ret;
+
+       /*
+        * Voltage is set at least to a level needed for this frequency,
+        * so switching clock source is safe now.
+        */
+       clk_prepare_enable(dmc->fout_spll);
+       clk_prepare_enable(dmc->mout_spll);
+       clk_prepare_enable(dmc->mout_mx_mspll_ccore);
+
+       ret = clk_set_parent(dmc->mout_mclk_cdrex, dmc->mout_mx_mspll_ccore);
+       if (ret)
+               goto disable_clocks;
+
+       /*
+        * We are safe to increase the timings for current bypass frequency.
+        * Thanks to this the settings will be ready for the upcoming clock
+        * source change.
+        */
+       exynos5_dram_change_timings(dmc, target_rate);
+
+       clk_set_rate(dmc->fout_bpll, target_rate);
+
+       exynos5_switch_timing_regs(dmc, USE_BPLL_TIMINGS);
+
+       ret = clk_set_parent(dmc->mout_mclk_cdrex, dmc->mout_bpll);
+       if (ret)
+               goto disable_clocks;
+
+       /*
+        * Make sure if the voltage is not from 'bypass' settings and align to
+        * the right level for power efficiency.
+        */
+       ret = exynos5_dmc_align_target_voltage(dmc, target_volt);
+
+disable_clocks:
+       clk_disable_unprepare(dmc->mout_mx_mspll_ccore);
+       clk_disable_unprepare(dmc->mout_spll);
+       clk_disable_unprepare(dmc->fout_spll);
+
+       return ret;
+}
+
+/**
+ * exynos5_dmc_get_volt_freq() - Gets the frequency and voltage from the OPP
+ * table.
+ * @dmc:       device for which the frequency is going to be changed
+ * @freq:       requested frequency in KHz
+ * @target_rate:       returned frequency which is the same or lower than
+ *                     requested
+ * @target_volt:       returned voltage which corresponds to the returned
+ *                     frequency
+ *
+ * Function gets requested frequency and checks OPP framework for needed
+ * frequency and voltage. It populates the values 'target_rate' and
+ * 'target_volt' or returns error value when OPP framework fails.
+ */
+static int exynos5_dmc_get_volt_freq(struct exynos5_dmc *dmc,
+                                    unsigned long *freq,
+                                    unsigned long *target_rate,
+                                    unsigned long *target_volt, u32 flags)
+{
+       struct dev_pm_opp *opp;
+
+       opp = devfreq_recommended_opp(dmc->dev, freq, flags);
+       if (IS_ERR(opp))
+               return PTR_ERR(opp);
+
+       *target_rate = dev_pm_opp_get_freq(opp);
+       *target_volt = dev_pm_opp_get_voltage(opp);
+       dev_pm_opp_put(opp);
+
+       return 0;
+}
+
+/**
+ * exynos5_dmc_target() - Function responsible for changing frequency of DMC
+ * @dev:       device for which the frequency is going to be changed
+ * @freq:      requested frequency in KHz
+ * @flags:     flags provided for this frequency change request
+ *
+ * An entry function provided to the devfreq framework which provides frequency
+ * change of the DMC. The function gets the possible rate from OPP table based
+ * on requested frequency. It calls the next function responsible for the
+ * frequency and voltage change. In case of failure, does not set 'curr_rate'
+ * and returns error value to the framework.
+ */
+static int exynos5_dmc_target(struct device *dev, unsigned long *freq,
+                             u32 flags)
+{
+       struct exynos5_dmc *dmc = dev_get_drvdata(dev);
+       unsigned long target_rate = 0;
+       unsigned long target_volt = 0;
+       int ret;
+
+       ret = exynos5_dmc_get_volt_freq(dmc, freq, &target_rate, &target_volt,
+                                       flags);
+
+       if (ret)
+               return ret;
+
+       if (target_rate == dmc->curr_rate)
+               return 0;
+
+       mutex_lock(&dmc->lock);
+
+       ret = exynos5_dmc_change_freq_and_volt(dmc, target_rate, target_volt);
+
+       if (ret) {
+               mutex_unlock(&dmc->lock);
+               return ret;
+       }
+
+       dmc->curr_rate = target_rate;
+
+       mutex_unlock(&dmc->lock);
+       return 0;
+}
+
+/**
+ * exynos5_counters_get() - Gets the performance counters values.
+ * @dmc:       device for which the counters are going to be checked
+ * @load_count:        variable which is populated with counter value
+ * @total_count:       variable which is used as 'wall clock' reference
+ *
+ * Function which provides performance counters values. It sums up counters for
+ * two DMC channels. The 'total_count' is used as a reference and max value.
+ * The ratio 'load_count/total_count' shows the busy percentage [0%, 100%].
+ */
+static int exynos5_counters_get(struct exynos5_dmc *dmc,
+                               unsigned long *load_count,
+                               unsigned long *total_count)
+{
+       unsigned long total = 0;
+       struct devfreq_event_data event;
+       int ret, i;
+
+       *load_count = 0;
+
+       /* Take into account only read+write counters, but stop all */
+       for (i = 0; i < dmc->num_counters; i++) {
+               if (!dmc->counter[i])
+                       continue;
+
+               ret = devfreq_event_get_event(dmc->counter[i], &event);
+               if (ret < 0)
+                       return ret;
+
+               *load_count += event.load_count;
+
+               if (total < event.total_count)
+                       total = event.total_count;
+       }
+
+       *total_count = total;
+
+       return 0;
+}
+
+/**
+ * exynos5_dmc_start_perf_events() - Setup and start performance event counters
+ * @dmc:       device for which the counters are going to be checked
+ * @beg_value: initial value for the counter
+ *
+ * Function which enables needed counters, interrupts and sets initial values
+ * then starts the counters.
+ */
+static void exynos5_dmc_start_perf_events(struct exynos5_dmc *dmc,
+                                         u32 beg_value)
+{
+       /* Enable interrupts for counter 2 */
+       writel(PERF_CNT2, dmc->base_drexi0 + DREX_INTENS_PPC);
+       writel(PERF_CNT2, dmc->base_drexi1 + DREX_INTENS_PPC);
+
+       /* Enable counter 2 and CCNT  */
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_CNTENS_PPC);
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_CNTENS_PPC);
+
+       /* Clear overflow flag for all counters */
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_FLAG_PPC);
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_FLAG_PPC);
+
+       /* Reset all counters */
+       writel(CC_RESET | PPC_COUNTER_RESET, dmc->base_drexi0 + DREX_PMNC_PPC);
+       writel(CC_RESET | PPC_COUNTER_RESET, dmc->base_drexi1 + DREX_PMNC_PPC);
+
+       /*
+        * Set start value for the counters, the number of samples that
+        * will be gathered is calculated as: 0xffffffff - beg_value
+        */
+       writel(beg_value, dmc->base_drexi0 + DREX_PMCNT2_PPC);
+       writel(beg_value, dmc->base_drexi1 + DREX_PMCNT2_PPC);
+
+       /* Start all counters */
+       writel(PPC_ENABLE, dmc->base_drexi0 + DREX_PMNC_PPC);
+       writel(PPC_ENABLE, dmc->base_drexi1 + DREX_PMNC_PPC);
+}
+
+/**
+ * exynos5_dmc_perf_events_calc() - Calculate utilization
+ * @dmc:       device for which the counters are going to be checked
+ * @diff_ts:   time between last interrupt and current one
+ *
+ * Function which calculates needed utilization for the devfreq governor.
+ * It prepares values for 'busy_time' and 'total_time' based on elapsed time
+ * between interrupts, which approximates utilization.
+ */
+static void exynos5_dmc_perf_events_calc(struct exynos5_dmc *dmc, u64 diff_ts)
+{
+       /*
+        * This is a simple algorithm for managing traffic on DMC.
+        * When there is almost no load the counters overflow every 4s,
+        * no mater the DMC frequency.
+        * The high load might be approximated using linear function.
+        * Knowing that, simple calculation can provide 'busy_time' and
+        * 'total_time' to the devfreq governor which picks up target
+        * frequency.
+        * We want a fast ramp up and slow decay in frequency change function.
+        */
+       if (diff_ts < PERF_EVENT_UP_DOWN_THRESHOLD) {
+               /*
+                * Set higher utilization for the simple_ondemand governor.
+                * The governor should increase the frequency of the DMC.
+                */
+               dmc->load = 70;
+               dmc->total = 100;
+       } else {
+               /*
+                * Set low utilization for the simple_ondemand governor.
+                * The governor should decrease the frequency of the DMC.
+                */
+               dmc->load = 35;
+               dmc->total = 100;
+       }
+
+       dev_dbg(dmc->dev, "diff_ts=%llu\n", diff_ts);
+}
+
+/**
+ * exynos5_dmc_perf_events_check() - Checks the status of the counters
+ * @dmc:       device for which the counters are going to be checked
+ *
+ * Function which is called from threaded IRQ to check the counters state
+ * and to call approximation for the needed utilization.
+ */
+static void exynos5_dmc_perf_events_check(struct exynos5_dmc *dmc)
+{
+       u32 val;
+       u64 diff_ts, ts;
+
+       ts = ktime_get_ns();
+
+       /* Stop all counters */
+       writel(0, dmc->base_drexi0 + DREX_PMNC_PPC);
+       writel(0, dmc->base_drexi1 + DREX_PMNC_PPC);
+
+       /* Check the source in interrupt flag registers (which channel) */
+       val = readl(dmc->base_drexi0 + DREX_FLAG_PPC);
+       if (val) {
+               diff_ts = ts - dmc->last_overflow_ts[0];
+               dmc->last_overflow_ts[0] = ts;
+               dev_dbg(dmc->dev, "drex0 0xE050 val= 0x%08x\n",  val);
+       } else {
+               val = readl(dmc->base_drexi1 + DREX_FLAG_PPC);
+               diff_ts = ts - dmc->last_overflow_ts[1];
+               dmc->last_overflow_ts[1] = ts;
+               dev_dbg(dmc->dev, "drex1 0xE050 val= 0x%08x\n",  val);
+       }
+
+       exynos5_dmc_perf_events_calc(dmc, diff_ts);
+
+       exynos5_dmc_start_perf_events(dmc, PERF_COUNTER_START_VALUE);
+}
+
+/**
+ * exynos5_dmc_enable_perf_events() - Enable performance events
+ * @dmc:       device for which the counters are going to be checked
+ *
+ * Function which is setup needed environment and enables counters.
+ */
+static void exynos5_dmc_enable_perf_events(struct exynos5_dmc *dmc)
+{
+       u64 ts;
+
+       /* Enable Performance Event Clock */
+       writel(PEREV_CLK_EN, dmc->base_drexi0 + DREX_PPCCLKCON);
+       writel(PEREV_CLK_EN, dmc->base_drexi1 + DREX_PPCCLKCON);
+
+       /* Select read transfers as performance event2 */
+       writel(READ_TRANSFER_CH0, dmc->base_drexi0 + DREX_PEREV2CONFIG);
+       writel(READ_TRANSFER_CH1, dmc->base_drexi1 + DREX_PEREV2CONFIG);
+
+       ts = ktime_get_ns();
+       dmc->last_overflow_ts[0] = ts;
+       dmc->last_overflow_ts[1] = ts;
+
+       /* Devfreq shouldn't be faster than initialization, play safe though. */
+       dmc->load = 99;
+       dmc->total = 100;
+}
+
+/**
+ * exynos5_dmc_disable_perf_events() - Disable performance events
+ * @dmc:       device for which the counters are going to be checked
+ *
+ * Function which stops, disables performance event counters and interrupts.
+ */
+static void exynos5_dmc_disable_perf_events(struct exynos5_dmc *dmc)
+{
+       /* Stop all counters */
+       writel(0, dmc->base_drexi0 + DREX_PMNC_PPC);
+       writel(0, dmc->base_drexi1 + DREX_PMNC_PPC);
+
+       /* Disable interrupts for counter 2 */
+       writel(PERF_CNT2, dmc->base_drexi0 + DREX_INTENC_PPC);
+       writel(PERF_CNT2, dmc->base_drexi1 + DREX_INTENC_PPC);
+
+       /* Disable counter 2 and CCNT  */
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_CNTENC_PPC);
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_CNTENC_PPC);
+
+       /* Clear overflow flag for all counters */
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_FLAG_PPC);
+       writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_FLAG_PPC);
+}
+
+/**
+ * exynos5_dmc_get_status() - Read current DMC performance statistics.
+ * @dev:       device for which the statistics are requested
+ * @stat:      structure which has statistic fields
+ *
+ * Function reads the DMC performance counters and calculates 'busy_time'
+ * and 'total_time'. To protect from overflow, the values are shifted right
+ * by 10. After read out the counters are setup to count again.
+ */
+static int exynos5_dmc_get_status(struct device *dev,
+                                 struct devfreq_dev_status *stat)
+{
+       struct exynos5_dmc *dmc = dev_get_drvdata(dev);
+       unsigned long load, total;
+       int ret;
+
+       if (dmc->in_irq_mode) {
+               stat->current_frequency = dmc->curr_rate;
+               stat->busy_time = dmc->load;
+               stat->total_time = dmc->total;
+       } else {
+               ret = exynos5_counters_get(dmc, &load, &total);
+               if (ret < 0)
+                       return -EINVAL;
+
+               /* To protect from overflow, divide by 1024 */
+               stat->busy_time = load >> 10;
+               stat->total_time = total >> 10;
+
+               ret = exynos5_counters_set_event(dmc);
+               if (ret < 0) {
+                       dev_err(dev, "could not set event counter\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * exynos5_dmc_get_cur_freq() - Function returns current DMC frequency
+ * @dev:       device for which the framework checks operating frequency
+ * @freq:      returned frequency value
+ *
+ * It returns the currently used frequency of the DMC. The real operating
+ * frequency might be lower when the clock source value could not be divided
+ * to the requested value.
+ */
+static int exynos5_dmc_get_cur_freq(struct device *dev, unsigned long *freq)
+{
+       struct exynos5_dmc *dmc = dev_get_drvdata(dev);
+
+       mutex_lock(&dmc->lock);
+       *freq = dmc->curr_rate;
+       mutex_unlock(&dmc->lock);
+
+       return 0;
+}
+
+/**
+ * exynos5_dmc_df_profile - Devfreq governor's profile structure
+ *
+ * It provides to the devfreq framework needed functions and polling period.
+ */
+static struct devfreq_dev_profile exynos5_dmc_df_profile = {
+       .target = exynos5_dmc_target,
+       .get_dev_status = exynos5_dmc_get_status,
+       .get_cur_freq = exynos5_dmc_get_cur_freq,
+};
+
+/**
+ * exynos5_dmc_align_initial_frequency() - Align initial frequency value
+ * @dmc:       device for which the frequency is going to be set
+ * @bootloader_init_freq:      initial frequency set by the bootloader in KHz
+ *
+ * The initial bootloader frequency, which is present during boot, might be
+ * different that supported frequency values in the driver. It is possible
+ * due to different PLL settings or used PLL as a source.
+ * This function provides the 'initial_freq' for the devfreq framework
+ * statistics engine which supports only registered values. Thus, some alignment
+ * must be made.
+ */
+static unsigned long
+exynos5_dmc_align_init_freq(struct exynos5_dmc *dmc,
+                           unsigned long bootloader_init_freq)
+{
+       unsigned long aligned_freq;
+       int idx;
+
+       idx = find_target_freq_idx(dmc, bootloader_init_freq);
+       if (idx >= 0)
+               aligned_freq = dmc->opp[idx].freq_hz;
+       else
+               aligned_freq = dmc->opp[dmc->opp_count - 1].freq_hz;
+
+       return aligned_freq;
+}
+
+/**
+ * create_timings_aligned() - Create register values and align with standard
+ * @dmc:       device for which the frequency is going to be set
+ * @idx:       speed bin in the OPP table
+ * @clk_period_ps:     the period of the clock, known as tCK
+ *
+ * The function calculates timings and creates a register value ready for
+ * a frequency transition. The register contains a few timings. They are
+ * shifted by a known offset. The timing value is calculated based on memory
+ * specyfication: minimal time required and minimal cycles required.
+ */
+static int create_timings_aligned(struct exynos5_dmc *dmc, u32 *reg_timing_row,
+                                 u32 *reg_timing_data, u32 *reg_timing_power,
+                                 u32 clk_period_ps)
+{
+       u32 val;
+       const struct timing_reg *reg;
+
+       if (clk_period_ps == 0)
+               return -EINVAL;
+
+       *reg_timing_row = 0;
+       *reg_timing_data = 0;
+       *reg_timing_power = 0;
+
+       val = dmc->timings->tRFC / clk_period_ps;
+       val += dmc->timings->tRFC % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRFC);
+       reg = &timing_row[0];
+       *reg_timing_row |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tRRD / clk_period_ps;
+       val += dmc->timings->tRRD % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRRD);
+       reg = &timing_row[1];
+       *reg_timing_row |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tRPab / clk_period_ps;
+       val += dmc->timings->tRPab % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRPab);
+       reg = &timing_row[2];
+       *reg_timing_row |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tRCD / clk_period_ps;
+       val += dmc->timings->tRCD % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRCD);
+       reg = &timing_row[3];
+       *reg_timing_row |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tRC / clk_period_ps;
+       val += dmc->timings->tRC % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRC);
+       reg = &timing_row[4];
+       *reg_timing_row |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tRAS / clk_period_ps;
+       val += dmc->timings->tRAS % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRAS);
+       reg = &timing_row[5];
+       *reg_timing_row |= TIMING_VAL2REG(reg, val);
+
+       /* data related timings */
+       val = dmc->timings->tWTR / clk_period_ps;
+       val += dmc->timings->tWTR % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tWTR);
+       reg = &timing_data[0];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tWR / clk_period_ps;
+       val += dmc->timings->tWR % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tWR);
+       reg = &timing_data[1];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tRTP / clk_period_ps;
+       val += dmc->timings->tRTP % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRTP);
+       reg = &timing_data[2];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tW2W_C2C / clk_period_ps;
+       val += dmc->timings->tW2W_C2C % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tW2W_C2C);
+       reg = &timing_data[3];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tR2R_C2C / clk_period_ps;
+       val += dmc->timings->tR2R_C2C % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tR2R_C2C);
+       reg = &timing_data[4];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tWL / clk_period_ps;
+       val += dmc->timings->tWL % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tWL);
+       reg = &timing_data[5];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tDQSCK / clk_period_ps;
+       val += dmc->timings->tDQSCK % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tDQSCK);
+       reg = &timing_data[6];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tRL / clk_period_ps;
+       val += dmc->timings->tRL % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tRL);
+       reg = &timing_data[7];
+       *reg_timing_data |= TIMING_VAL2REG(reg, val);
+
+       /* power related timings */
+       val = dmc->timings->tFAW / clk_period_ps;
+       val += dmc->timings->tFAW % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tXP);
+       reg = &timing_power[0];
+       *reg_timing_power |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tXSR / clk_period_ps;
+       val += dmc->timings->tXSR % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tXSR);
+       reg = &timing_power[1];
+       *reg_timing_power |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tXP / clk_period_ps;
+       val += dmc->timings->tXP % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tXP);
+       reg = &timing_power[2];
+       *reg_timing_power |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tCKE / clk_period_ps;
+       val += dmc->timings->tCKE % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tCKE);
+       reg = &timing_power[3];
+       *reg_timing_power |= TIMING_VAL2REG(reg, val);
+
+       val = dmc->timings->tMRD / clk_period_ps;
+       val += dmc->timings->tMRD % clk_period_ps ? 1 : 0;
+       val = max(val, dmc->min_tck->tMRD);
+       reg = &timing_power[4];
+       *reg_timing_power |= TIMING_VAL2REG(reg, val);
+
+       return 0;
+}
+
+/**
+ * of_get_dram_timings() - helper function for parsing DT settings for DRAM
+ * @dmc:        device for which the frequency is going to be set
+ *
+ * The function parses DT entries with DRAM information.
+ */
+static int of_get_dram_timings(struct exynos5_dmc *dmc)
+{
+       int ret = 0;
+       int idx;
+       struct device_node *np_ddr;
+       u32 freq_mhz, clk_period_ps;
+
+       np_ddr = of_parse_phandle(dmc->dev->of_node, "device-handle", 0);
+       if (!np_ddr) {
+               dev_warn(dmc->dev, "could not find 'device-handle' in DT\n");
+               return -EINVAL;
+       }
+
+       dmc->timing_row = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
+                                            sizeof(u32), GFP_KERNEL);
+       if (!dmc->timing_row)
+               return -ENOMEM;
+
+       dmc->timing_data = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
+                                             sizeof(u32), GFP_KERNEL);
+       if (!dmc->timing_data)
+               return -ENOMEM;
+
+       dmc->timing_power = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
+                                              sizeof(u32), GFP_KERNEL);
+       if (!dmc->timing_power)
+               return -ENOMEM;
+
+       dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dmc->dev,
+                                                DDR_TYPE_LPDDR3,
+                                                &dmc->timings_arr_size);
+       if (!dmc->timings) {
+               of_node_put(np_ddr);
+               dev_warn(dmc->dev, "could not get timings from DT\n");
+               return -EINVAL;
+       }
+
+       dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dmc->dev);
+       if (!dmc->min_tck) {
+               of_node_put(np_ddr);
+               dev_warn(dmc->dev, "could not get tck from DT\n");
+               return -EINVAL;
+       }
+
+       /* Sorted array of OPPs with frequency ascending */
+       for (idx = 0; idx < dmc->opp_count; idx++) {
+               freq_mhz = dmc->opp[idx].freq_hz / 1000000;
+               clk_period_ps = 1000000 / freq_mhz;
+
+               ret = create_timings_aligned(dmc, &dmc->timing_row[idx],
+                                            &dmc->timing_data[idx],
+                                            &dmc->timing_power[idx],
+                                            clk_period_ps);
+       }
+
+       of_node_put(np_ddr);
+
+       /* Take the highest frequency's timings as 'bypass' */
+       dmc->bypass_timing_row = dmc->timing_row[idx - 1];
+       dmc->bypass_timing_data = dmc->timing_data[idx - 1];
+       dmc->bypass_timing_power = dmc->timing_power[idx - 1];
+
+       return ret;
+}
+
+/**
+ * exynos5_dmc_init_clks() - Initialize clocks needed for DMC operation.
+ * @dmc:       DMC structure containing needed fields
+ *
+ * Get the needed clocks defined in DT device, enable and set the right parents.
+ * Read current frequency and initialize the initial rate for governor.
+ */
+static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc)
+{
+       int ret;
+       unsigned long target_volt = 0;
+       unsigned long target_rate = 0;
+       unsigned int tmp;
+
+       dmc->fout_spll = devm_clk_get(dmc->dev, "fout_spll");
+       if (IS_ERR(dmc->fout_spll))
+               return PTR_ERR(dmc->fout_spll);
+
+       dmc->fout_bpll = devm_clk_get(dmc->dev, "fout_bpll");
+       if (IS_ERR(dmc->fout_bpll))
+               return PTR_ERR(dmc->fout_bpll);
+
+       dmc->mout_mclk_cdrex = devm_clk_get(dmc->dev, "mout_mclk_cdrex");
+       if (IS_ERR(dmc->mout_mclk_cdrex))
+               return PTR_ERR(dmc->mout_mclk_cdrex);
+
+       dmc->mout_bpll = devm_clk_get(dmc->dev, "mout_bpll");
+       if (IS_ERR(dmc->mout_bpll))
+               return PTR_ERR(dmc->mout_bpll);
+
+       dmc->mout_mx_mspll_ccore = devm_clk_get(dmc->dev,
+                                               "mout_mx_mspll_ccore");
+       if (IS_ERR(dmc->mout_mx_mspll_ccore))
+               return PTR_ERR(dmc->mout_mx_mspll_ccore);
+
+       dmc->mout_spll = devm_clk_get(dmc->dev, "ff_dout_spll2");
+       if (IS_ERR(dmc->mout_spll)) {
+               dmc->mout_spll = devm_clk_get(dmc->dev, "mout_sclk_spll");
+               if (IS_ERR(dmc->mout_spll))
+                       return PTR_ERR(dmc->mout_spll);
+       }
+
+       /*
+        * Convert frequency to KHz values and set it for the governor.
+        */
+       dmc->curr_rate = clk_get_rate(dmc->mout_mclk_cdrex);
+       dmc->curr_rate = exynos5_dmc_align_init_freq(dmc, dmc->curr_rate);
+       exynos5_dmc_df_profile.initial_freq = dmc->curr_rate;
+
+       ret = exynos5_dmc_get_volt_freq(dmc, &dmc->curr_rate, &target_rate,
+                                       &target_volt, 0);
+       if (ret)
+               return ret;
+
+       dmc->curr_volt = target_volt;
+
+       clk_set_parent(dmc->mout_mx_mspll_ccore, dmc->mout_spll);
+
+       dmc->bypass_rate = clk_get_rate(dmc->mout_mx_mspll_ccore);
+
+       clk_prepare_enable(dmc->fout_bpll);
+       clk_prepare_enable(dmc->mout_bpll);
+
+       /*
+        * Some bootloaders do not set clock routes correctly.
+        * Stop one path in clocks to PHY.
+        */
+       regmap_read(dmc->clk_regmap, CDREX_LPDDR3PHY_CLKM_SRC, &tmp);
+       tmp &= ~(BIT(1) | BIT(0));
+       regmap_write(dmc->clk_regmap, CDREX_LPDDR3PHY_CLKM_SRC, tmp);
+
+       return 0;
+}
+
+/**
+ * exynos5_performance_counters_init() - Initializes performance DMC's counters
+ * @dmc:       DMC for which it does the setup
+ *
+ * Initialization of performance counters in DMC for estimating usage.
+ * The counter's values are used for calculation of a memory bandwidth and based
+ * on that the governor changes the frequency.
+ * The counters are not used when the governor is GOVERNOR_USERSPACE.
+ */
+static int exynos5_performance_counters_init(struct exynos5_dmc *dmc)
+{
+       int counters_size;
+       int ret, i;
+
+       dmc->num_counters = devfreq_event_get_edev_count(dmc->dev);
+       if (dmc->num_counters < 0) {
+               dev_err(dmc->dev, "could not get devfreq-event counters\n");
+               return dmc->num_counters;
+       }
+
+       counters_size = sizeof(struct devfreq_event_dev) * dmc->num_counters;
+       dmc->counter = devm_kzalloc(dmc->dev, counters_size, GFP_KERNEL);
+       if (!dmc->counter)
+               return -ENOMEM;
+
+       for (i = 0; i < dmc->num_counters; i++) {
+               dmc->counter[i] =
+                       devfreq_event_get_edev_by_phandle(dmc->dev, i);
+               if (IS_ERR_OR_NULL(dmc->counter[i]))
+                       return -EPROBE_DEFER;
+       }
+
+       ret = exynos5_counters_enable_edev(dmc);
+       if (ret < 0) {
+               dev_err(dmc->dev, "could not enable event counter\n");
+               return ret;
+       }
+
+       ret = exynos5_counters_set_event(dmc);
+       if (ret < 0) {
+               exynos5_counters_disable_edev(dmc);
+               dev_err(dmc->dev, "could not set event counter\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
+ * exynos5_dmc_set_pause_on_switching() - Controls a pause feature in DMC
+ * @dmc:       device which is used for changing this feature
+ * @set:       a boolean state passing enable/disable request
+ *
+ * There is a need of pausing DREX DMC when divider or MUX in clock tree
+ * changes its configuration. In such situation access to the memory is blocked
+ * in DMC automatically. This feature is used when clock frequency change
+ * request appears and touches clock tree.
+ */
+static inline int exynos5_dmc_set_pause_on_switching(struct exynos5_dmc *dmc)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(dmc->clk_regmap, CDREX_PAUSE, &val);
+       if (ret)
+               return ret;
+
+       val |= 1UL;
+       regmap_write(dmc->clk_regmap, CDREX_PAUSE, val);
+
+       return 0;
+}
+
+static irqreturn_t dmc_irq_thread(int irq, void *priv)
+{
+       int res;
+       struct exynos5_dmc *dmc = priv;
+
+       mutex_lock(&dmc->df->lock);
+
+       exynos5_dmc_perf_events_check(dmc);
+
+       res = update_devfreq(dmc->df);
+       if (res)
+               dev_warn(dmc->dev, "devfreq failed with %d\n", res);
+
+       mutex_unlock(&dmc->df->lock);
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * exynos5_dmc_probe() - Probe function for the DMC driver
+ * @pdev:      platform device for which the driver is going to be initialized
+ *
+ * Initialize basic components: clocks, regulators, performance counters, etc.
+ * Read out product version and based on the information setup
+ * internal structures for the controller (frequency and voltage) and for DRAM
+ * memory parameters: timings for each operating frequency.
+ * Register new devfreq device for controlling DVFS of the DMC.
+ */
+static int exynos5_dmc_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct exynos5_dmc *dmc;
+       struct resource *res;
+       int irq[2];
+
+       dmc = devm_kzalloc(dev, sizeof(*dmc), GFP_KERNEL);
+       if (!dmc)
+               return -ENOMEM;
+
+       mutex_init(&dmc->lock);
+
+       dmc->dev = dev;
+       platform_set_drvdata(pdev, dmc);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       dmc->base_drexi0 = devm_ioremap_resource(dev, res);
+       if (IS_ERR(dmc->base_drexi0))
+               return PTR_ERR(dmc->base_drexi0);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       dmc->base_drexi1 = devm_ioremap_resource(dev, res);
+       if (IS_ERR(dmc->base_drexi1))
+               return PTR_ERR(dmc->base_drexi1);
+
+       dmc->clk_regmap = syscon_regmap_lookup_by_phandle(np,
+                               "samsung,syscon-clk");
+       if (IS_ERR(dmc->clk_regmap))
+               return PTR_ERR(dmc->clk_regmap);
+
+       ret = exynos5_init_freq_table(dmc, &exynos5_dmc_df_profile);
+       if (ret) {
+               dev_warn(dev, "couldn't initialize frequency settings\n");
+               return ret;
+       }
+
+       dmc->vdd_mif = devm_regulator_get(dev, "vdd");
+       if (IS_ERR(dmc->vdd_mif)) {
+               ret = PTR_ERR(dmc->vdd_mif);
+               return ret;
+       }
+
+       ret = exynos5_dmc_init_clks(dmc);
+       if (ret)
+               return ret;
+
+       ret = of_get_dram_timings(dmc);
+       if (ret) {
+               dev_warn(dev, "couldn't initialize timings settings\n");
+               goto remove_clocks;
+       }
+
+       ret = exynos5_dmc_set_pause_on_switching(dmc);
+       if (ret) {
+               dev_warn(dev, "couldn't get access to PAUSE register\n");
+               goto remove_clocks;
+       }
+
+       /* There is two modes in which the driver works: polling or IRQ */
+       irq[0] = platform_get_irq_byname(pdev, "drex_0");
+       irq[1] = platform_get_irq_byname(pdev, "drex_1");
+       if (irq[0] > 0 && irq[1] > 0) {
+               ret = devm_request_threaded_irq(dev, irq[0], NULL,
+                                               dmc_irq_thread, IRQF_ONESHOT,
+                                               dev_name(dev), dmc);
+               if (ret) {
+                       dev_err(dev, "couldn't grab IRQ\n");
+                       goto remove_clocks;
+               }
+
+               ret = devm_request_threaded_irq(dev, irq[1], NULL,
+                                               dmc_irq_thread, IRQF_ONESHOT,
+                                               dev_name(dev), dmc);
+               if (ret) {
+                       dev_err(dev, "couldn't grab IRQ\n");
+                       goto remove_clocks;
+               }
+
+               /*
+                * Setup default thresholds for the devfreq governor.
+                * The values are chosen based on experiments.
+                */
+               dmc->gov_data.upthreshold = 55;
+               dmc->gov_data.downdifferential = 5;
+
+               exynos5_dmc_enable_perf_events(dmc);
+
+               dmc->in_irq_mode = 1;
+       } else {
+               ret = exynos5_performance_counters_init(dmc);
+               if (ret) {
+                       dev_warn(dev, "couldn't probe performance counters\n");
+                       goto remove_clocks;
+               }
+
+               /*
+                * Setup default thresholds for the devfreq governor.
+                * The values are chosen based on experiments.
+                */
+               dmc->gov_data.upthreshold = 30;
+               dmc->gov_data.downdifferential = 5;
+
+               exynos5_dmc_df_profile.polling_ms = 500;
+       }
+
+
+       dmc->df = devm_devfreq_add_device(dev, &exynos5_dmc_df_profile,
+                                         DEVFREQ_GOV_SIMPLE_ONDEMAND,
+                                         &dmc->gov_data);
+
+       if (IS_ERR(dmc->df)) {
+               ret = PTR_ERR(dmc->df);
+               goto err_devfreq_add;
+       }
+
+       if (dmc->in_irq_mode)
+               exynos5_dmc_start_perf_events(dmc, PERF_COUNTER_START_VALUE);
+
+       dev_info(dev, "DMC initialized\n");
+
+       return 0;
+
+err_devfreq_add:
+       if (dmc->in_irq_mode)
+               exynos5_dmc_disable_perf_events(dmc);
+       else
+               exynos5_counters_disable_edev(dmc);
+remove_clocks:
+       clk_disable_unprepare(dmc->mout_bpll);
+       clk_disable_unprepare(dmc->fout_bpll);
+
+       return ret;
+}
+
+/**
+ * exynos5_dmc_remove() - Remove function for the platform device
+ * @pdev:      platform device which is going to be removed
+ *
+ * The function relies on 'devm' framework function which automatically
+ * clean the device's resources. It just calls explicitly disable function for
+ * the performance counters.
+ */
+static int exynos5_dmc_remove(struct platform_device *pdev)
+{
+       struct exynos5_dmc *dmc = dev_get_drvdata(&pdev->dev);
+
+       if (dmc->in_irq_mode)
+               exynos5_dmc_disable_perf_events(dmc);
+       else
+               exynos5_counters_disable_edev(dmc);
+
+       clk_disable_unprepare(dmc->mout_bpll);
+       clk_disable_unprepare(dmc->fout_bpll);
+
+       dev_pm_opp_remove_table(dmc->dev);
+
+       return 0;
+}
+
+static const struct of_device_id exynos5_dmc_of_match[] = {
+       { .compatible = "samsung,exynos5422-dmc", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, exynos5_dmc_of_match);
+
+static struct platform_driver exynos5_dmc_platdrv = {
+       .probe  = exynos5_dmc_probe,
+       .remove = exynos5_dmc_remove,
+       .driver = {
+               .name   = "exynos5-dmc",
+               .of_match_table = exynos5_dmc_of_match,
+       },
+};
+module_platform_driver(exynos5_dmc_platdrv);
+MODULE_DESCRIPTION("Driver for Exynos5422 Dynamic Memory Controller dynamic frequency and voltage change");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Lukasz Luba");
index 4680124..fbfbaad 100644 (file)
@@ -17,6 +17,16 @@ config TEGRA20_EMC
          This driver is required to change memory timings / clock rate for
          external memory.
 
+config TEGRA30_EMC
+       bool "NVIDIA Tegra30 External Memory Controller driver"
+       default y
+       depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
+       help
+         This driver is for the External Memory Controller (EMC) found on
+         Tegra30 chips. The EMC controls the external DRAM on the board.
+         This driver is required to change memory timings / clock rate for
+         external memory.
+
 config TEGRA124_EMC
        bool "NVIDIA Tegra124 External Memory Controller driver"
        default y
index 3971a6b..3d23c42 100644 (file)
@@ -11,5 +11,6 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
 obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
 
 obj-$(CONFIG_TEGRA20_EMC)  += tegra20-emc.o
+obj-$(CONFIG_TEGRA30_EMC)  += tegra30-emc.o
 obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o
 obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
index 3d8d322..ec84035 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 
 #include "mc.h"
 
-#define MC_INTSTATUS 0x000
-
-#define MC_INTMASK 0x004
-
-#define MC_ERR_STATUS 0x08
-#define  MC_ERR_STATUS_TYPE_SHIFT 28
-#define  MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE (6 << MC_ERR_STATUS_TYPE_SHIFT)
-#define  MC_ERR_STATUS_TYPE_MASK (0x7 << MC_ERR_STATUS_TYPE_SHIFT)
-#define  MC_ERR_STATUS_READABLE (1 << 27)
-#define  MC_ERR_STATUS_WRITABLE (1 << 26)
-#define  MC_ERR_STATUS_NONSECURE (1 << 25)
-#define  MC_ERR_STATUS_ADR_HI_SHIFT 20
-#define  MC_ERR_STATUS_ADR_HI_MASK 0x3
-#define  MC_ERR_STATUS_SECURITY (1 << 17)
-#define  MC_ERR_STATUS_RW (1 << 16)
-
-#define MC_ERR_ADR 0x0c
-
-#define MC_GART_ERROR_REQ              0x30
-#define MC_DECERR_EMEM_OTHERS_STATUS   0x58
-#define MC_SECURITY_VIOLATION_STATUS   0x74
-
-#define MC_EMEM_ARB_CFG 0x90
-#define  MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x)  (((x) & 0x1ff) << 0)
-#define  MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK        0x1ff
-#define MC_EMEM_ARB_MISC0 0xd8
-
-#define MC_EMEM_ADR_CFG 0x54
-#define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0)
-
-#define MC_TIMING_CONTROL              0xfc
-#define MC_TIMING_UPDATE               BIT(0)
-
 static const struct of_device_id tegra_mc_of_match[] = {
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
        { .compatible = "nvidia,tegra20-mc-gart", .data = &tegra20_mc_soc },
@@ -307,7 +275,7 @@ static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
        return 0;
 }
 
-void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
+int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
 {
        unsigned int i;
        struct tegra_mc_timing *timing = NULL;
@@ -322,11 +290,13 @@ void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
        if (!timing) {
                dev_err(mc->dev, "no memory timing registered for rate %lu\n",
                        rate);
-               return;
+               return -EINVAL;
        }
 
        for (i = 0; i < mc->soc->num_emem_regs; ++i)
                mc_writel(mc, timing->emem_data[i], mc->soc->emem_regs[i]);
+
+       return 0;
 }
 
 unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
@@ -626,6 +596,7 @@ static int tegra_mc_probe(struct platform_device *pdev)
        struct resource *res;
        struct tegra_mc *mc;
        void *isr;
+       u64 mask;
        int err;
 
        mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
@@ -637,6 +608,14 @@ static int tegra_mc_probe(struct platform_device *pdev)
        mc->soc = of_device_get_match_data(&pdev->dev);
        mc->dev = &pdev->dev;
 
+       mask = DMA_BIT_MASK(mc->soc->num_address_bits);
+
+       err = dma_coerce_mask_and_coherent(&pdev->dev, mask);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to set DMA mask: %d\n", err);
+               return err;
+       }
+
        /* length of MC tick in nanoseconds */
        mc->tick = 30;
 
@@ -658,6 +637,9 @@ static int tegra_mc_probe(struct platform_device *pdev)
        } else
 #endif
        {
+               /* ensure that debug features are disabled */
+               mc_writel(mc, 0x00000000, MC_TIMING_CONTROL_DBG);
+
                err = tegra_mc_setup_latency_allowance(mc);
                if (err < 0) {
                        dev_err(&pdev->dev,
index f935349..957c6eb 100644 (file)
@@ -6,20 +6,76 @@
 #ifndef MEMORY_TEGRA_MC_H
 #define MEMORY_TEGRA_MC_H
 
+#include <linux/bits.h>
 #include <linux/io.h>
 #include <linux/types.h>
 
 #include <soc/tegra/mc.h>
 
-#define MC_INT_DECERR_MTS (1 << 16)
-#define MC_INT_SECERR_SEC (1 << 13)
-#define MC_INT_DECERR_VPR (1 << 12)
-#define MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
-#define MC_INT_INVALID_SMMU_PAGE (1 << 10)
-#define MC_INT_ARBITRATION_EMEM (1 << 9)
-#define MC_INT_SECURITY_VIOLATION (1 << 8)
-#define MC_INT_INVALID_GART_PAGE (1 << 7)
-#define MC_INT_DECERR_EMEM (1 << 6)
+#define MC_INTSTATUS                                   0x00
+#define MC_INTMASK                                     0x04
+#define MC_ERR_STATUS                                  0x08
+#define MC_ERR_ADR                                     0x0c
+#define MC_GART_ERROR_REQ                              0x30
+#define MC_EMEM_ADR_CFG                                        0x54
+#define MC_DECERR_EMEM_OTHERS_STATUS                   0x58
+#define MC_SECURITY_VIOLATION_STATUS                   0x74
+#define MC_EMEM_ARB_CFG                                        0x90
+#define MC_EMEM_ARB_OUTSTANDING_REQ                    0x94
+#define MC_EMEM_ARB_TIMING_RCD                         0x98
+#define MC_EMEM_ARB_TIMING_RP                          0x9c
+#define MC_EMEM_ARB_TIMING_RC                          0xa0
+#define MC_EMEM_ARB_TIMING_RAS                         0xa4
+#define MC_EMEM_ARB_TIMING_FAW                         0xa8
+#define MC_EMEM_ARB_TIMING_RRD                         0xac
+#define MC_EMEM_ARB_TIMING_RAP2PRE                     0xb0
+#define MC_EMEM_ARB_TIMING_WAP2PRE                     0xb4
+#define MC_EMEM_ARB_TIMING_R2R                         0xb8
+#define MC_EMEM_ARB_TIMING_W2W                         0xbc
+#define MC_EMEM_ARB_TIMING_R2W                         0xc0
+#define MC_EMEM_ARB_TIMING_W2R                         0xc4
+#define MC_EMEM_ARB_DA_TURNS                           0xd0
+#define MC_EMEM_ARB_DA_COVERS                          0xd4
+#define MC_EMEM_ARB_MISC0                              0xd8
+#define MC_EMEM_ARB_MISC1                              0xdc
+#define MC_EMEM_ARB_RING1_THROTTLE                     0xe0
+#define MC_EMEM_ARB_OVERRIDE                           0xe8
+#define MC_TIMING_CONTROL_DBG                          0xf8
+#define MC_TIMING_CONTROL                              0xfc
+
+#define MC_INT_DECERR_MTS                              BIT(16)
+#define MC_INT_SECERR_SEC                              BIT(13)
+#define MC_INT_DECERR_VPR                              BIT(12)
+#define MC_INT_INVALID_APB_ASID_UPDATE                 BIT(11)
+#define MC_INT_INVALID_SMMU_PAGE                       BIT(10)
+#define MC_INT_ARBITRATION_EMEM                                BIT(9)
+#define MC_INT_SECURITY_VIOLATION                      BIT(8)
+#define MC_INT_INVALID_GART_PAGE                       BIT(7)
+#define MC_INT_DECERR_EMEM                             BIT(6)
+
+#define MC_ERR_STATUS_TYPE_SHIFT                       28
+#define MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE           (0x6 << 28)
+#define MC_ERR_STATUS_TYPE_MASK                                (0x7 << 28)
+#define MC_ERR_STATUS_READABLE                         BIT(27)
+#define MC_ERR_STATUS_WRITABLE                         BIT(26)
+#define MC_ERR_STATUS_NONSECURE                                BIT(25)
+#define MC_ERR_STATUS_ADR_HI_SHIFT                     20
+#define MC_ERR_STATUS_ADR_HI_MASK                      0x3
+#define MC_ERR_STATUS_SECURITY                         BIT(17)
+#define MC_ERR_STATUS_RW                               BIT(16)
+
+#define MC_EMEM_ADR_CFG_EMEM_NUMDEV                    BIT(0)
+
+#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x)           ((x) & 0x1ff)
+#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK         0x1ff
+
+#define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK           0x1ff
+#define MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE   BIT(30)
+#define MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE       BIT(31)
+
+#define MC_EMEM_ARB_OVERRIDE_EACK_MASK                 0x3
+
+#define MC_TIMING_UPDATE                               BIT(0)
 
 static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
 {
index ac8351b..48ef01c 100644 (file)
@@ -909,16 +909,18 @@ static const struct tegra_smmu_swgroup tegra114_swgroups[] = {
        { .name = "tsec",      .swgroup = TEGRA_SWGROUP_TSEC,      .reg = 0x294 },
 };
 
-static const unsigned int tegra114_group_display[] = {
+static const unsigned int tegra114_group_drm[] = {
        TEGRA_SWGROUP_DC,
        TEGRA_SWGROUP_DCB,
+       TEGRA_SWGROUP_G2,
+       TEGRA_SWGROUP_NV,
 };
 
 static const struct tegra_smmu_group_soc tegra114_groups[] = {
        {
-               .name = "display",
-               .swgroups = tegra114_group_display,
-               .num_swgroups = ARRAY_SIZE(tegra114_group_display),
+               .name = "drm",
+               .swgroups = tegra114_group_drm,
+               .num_swgroups = ARRAY_SIZE(tegra114_group_drm),
        },
 };
 
index 5d0ccb2..493b5dc 100644 (file)
 
 #include "mc.h"
 
-#define MC_EMEM_ARB_CFG                                0x90
-#define MC_EMEM_ARB_OUTSTANDING_REQ            0x94
-#define MC_EMEM_ARB_TIMING_RCD                 0x98
-#define MC_EMEM_ARB_TIMING_RP                  0x9c
-#define MC_EMEM_ARB_TIMING_RC                  0xa0
-#define MC_EMEM_ARB_TIMING_RAS                 0xa4
-#define MC_EMEM_ARB_TIMING_FAW                 0xa8
-#define MC_EMEM_ARB_TIMING_RRD                 0xac
-#define MC_EMEM_ARB_TIMING_RAP2PRE             0xb0
-#define MC_EMEM_ARB_TIMING_WAP2PRE             0xb4
-#define MC_EMEM_ARB_TIMING_R2R                 0xb8
-#define MC_EMEM_ARB_TIMING_W2W                 0xbc
-#define MC_EMEM_ARB_TIMING_R2W                 0xc0
-#define MC_EMEM_ARB_TIMING_W2R                 0xc4
-#define MC_EMEM_ARB_DA_TURNS                   0xd0
-#define MC_EMEM_ARB_DA_COVERS                  0xd4
-#define MC_EMEM_ARB_MISC0                      0xd8
-#define MC_EMEM_ARB_MISC1                      0xdc
-#define MC_EMEM_ARB_RING1_THROTTLE             0xe0
-
 static const struct tegra_mc_client tegra124_mc_clients[] = {
        {
                .id = 0x00,
@@ -974,16 +954,18 @@ static const struct tegra_smmu_swgroup tegra124_swgroups[] = {
        { .name = "vi",        .swgroup = TEGRA_SWGROUP_VI,        .reg = 0x280 },
 };
 
-static const unsigned int tegra124_group_display[] = {
+static const unsigned int tegra124_group_drm[] = {
        TEGRA_SWGROUP_DC,
        TEGRA_SWGROUP_DCB,
+       TEGRA_SWGROUP_GPU,
+       TEGRA_SWGROUP_VIC,
 };
 
 static const struct tegra_smmu_group_soc tegra124_groups[] = {
        {
-               .name = "display",
-               .swgroups = tegra124_group_display,
-               .num_swgroups = ARRAY_SIZE(tegra124_group_display),
+               .name = "drm",
+               .swgroups = tegra124_group_drm,
+               .num_swgroups = ARRAY_SIZE(tegra124_group_drm),
        },
 };
 
index 9ee5bef..1b23b1c 100644 (file)
@@ -6,10 +6,11 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk/tegra.h>
 #include <linux/completion.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
-#include <linux/iopoll.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -21,6 +22,7 @@
 
 #define EMC_INTSTATUS                          0x000
 #define EMC_INTMASK                            0x004
+#define EMC_DBG                                        0x008
 #define EMC_TIMING_CONTROL                     0x028
 #define EMC_RC                                 0x02c
 #define EMC_RFC                                        0x030
 #define EMC_REFRESH_OVERFLOW_INT               BIT(3)
 #define EMC_CLKCHANGE_COMPLETE_INT             BIT(4)
 
+#define EMC_DBG_READ_MUX_ASSEMBLY              BIT(0)
+#define EMC_DBG_WRITE_MUX_ACTIVE               BIT(1)
+#define EMC_DBG_FORCE_UPDATE                   BIT(2)
+#define EMC_DBG_READ_DQM_CTRL                  BIT(9)
+#define EMC_DBG_CFG_PRIORITY                   BIT(24)
+
 static const u16 emc_timing_registers[] = {
        EMC_RC,
        EMC_RFC,
@@ -137,9 +145,6 @@ struct tegra_emc {
        struct device *dev;
        struct completion clk_handshake_complete;
        struct notifier_block clk_nb;
-       struct clk *backup_clk;
-       struct clk *emc_mux;
-       struct clk *pll_m;
        struct clk *clk;
        void __iomem *regs;
 
@@ -219,7 +224,7 @@ static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
 
 static int emc_complete_timing_change(struct tegra_emc *emc, bool flush)
 {
-       long timeout;
+       unsigned long timeout;
 
        dev_dbg(emc->dev, "%s: flush %d\n", __func__, flush);
 
@@ -231,14 +236,10 @@ static int emc_complete_timing_change(struct tegra_emc *emc, bool flush)
        }
 
        timeout = wait_for_completion_timeout(&emc->clk_handshake_complete,
-                                             usecs_to_jiffies(100));
+                                             msecs_to_jiffies(100));
        if (timeout == 0) {
                dev_err(emc->dev, "EMC-CAR handshake failed\n");
                return -EIO;
-       } else if (timeout < 0) {
-               dev_err(emc->dev, "failed to wait for EMC-CAR handshake: %ld\n",
-                       timeout);
-               return timeout;
        }
 
        return 0;
@@ -363,6 +364,13 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
        sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings,
             NULL);
 
+       dev_info(emc->dev,
+                "got %u timings for RAM code %u (min %luMHz max %luMHz)\n",
+                emc->num_timings,
+                tegra_read_ram_code(),
+                emc->timings[0].rate / 1000000,
+                emc->timings[emc->num_timings - 1].rate / 1000000);
+
        return 0;
 }
 
@@ -398,7 +406,7 @@ tegra_emc_find_node_by_ram_code(struct device *dev)
 static int emc_setup_hw(struct tegra_emc *emc)
 {
        u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
-       u32 emc_cfg;
+       u32 emc_cfg, emc_dbg;
 
        emc_cfg = readl_relaxed(emc->regs + EMC_CFG_2);
 
@@ -421,42 +429,53 @@ static int emc_setup_hw(struct tegra_emc *emc)
        writel_relaxed(intmask, emc->regs + EMC_INTMASK);
        writel_relaxed(intmask, emc->regs + EMC_INTSTATUS);
 
+       /* ensure that unwanted debug features are disabled */
+       emc_dbg = readl_relaxed(emc->regs + EMC_DBG);
+       emc_dbg |= EMC_DBG_CFG_PRIORITY;
+       emc_dbg &= ~EMC_DBG_READ_MUX_ASSEMBLY;
+       emc_dbg &= ~EMC_DBG_WRITE_MUX_ACTIVE;
+       emc_dbg &= ~EMC_DBG_FORCE_UPDATE;
+       writel_relaxed(emc_dbg, emc->regs + EMC_DBG);
+
        return 0;
 }
 
-static int emc_init(struct tegra_emc *emc, unsigned long rate)
+static long emc_round_rate(unsigned long rate,
+                          unsigned long min_rate,
+                          unsigned long max_rate,
+                          void *arg)
 {
-       int err;
+       struct emc_timing *timing = NULL;
+       struct tegra_emc *emc = arg;
+       unsigned int i;
 
-       err = clk_set_parent(emc->emc_mux, emc->backup_clk);
-       if (err) {
-               dev_err(emc->dev,
-                       "failed to reparent to backup source: %d\n", err);
-               return err;
-       }
+       min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
 
-       err = clk_set_rate(emc->pll_m, rate);
-       if (err) {
-               dev_err(emc->dev,
-                       "failed to change pll_m rate: %d\n", err);
-               return err;
-       }
+       for (i = 0; i < emc->num_timings; i++) {
+               if (emc->timings[i].rate < rate && i != emc->num_timings - 1)
+                       continue;
 
-       err = clk_set_parent(emc->emc_mux, emc->pll_m);
-       if (err) {
-               dev_err(emc->dev,
-                       "failed to reparent to pll_m: %d\n", err);
-               return err;
+               if (emc->timings[i].rate > max_rate) {
+                       i = max(i, 1u) - 1;
+
+                       if (emc->timings[i].rate < min_rate)
+                               break;
+               }
+
+               if (emc->timings[i].rate < min_rate)
+                       continue;
+
+               timing = &emc->timings[i];
+               break;
        }
 
-       err = clk_set_rate(emc->clk, rate);
-       if (err) {
-               dev_err(emc->dev,
-                       "failed to change emc rate: %d\n", err);
-               return err;
+       if (!timing) {
+               dev_err(emc->dev, "no timing for rate %lu min %lu max %lu\n",
+                       rate, min_rate, max_rate);
+               return -EINVAL;
        }
 
-       return 0;
+       return timing->rate;
 }
 
 static int tegra_emc_probe(struct platform_device *pdev)
@@ -515,57 +534,26 @@ static int tegra_emc_probe(struct platform_device *pdev)
                return err;
        }
 
+       tegra20_clk_set_emc_round_callback(emc_round_rate, emc);
+
        emc->clk = devm_clk_get(&pdev->dev, "emc");
        if (IS_ERR(emc->clk)) {
                err = PTR_ERR(emc->clk);
                dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
-               return err;
-       }
-
-       emc->pll_m = clk_get_sys(NULL, "pll_m");
-       if (IS_ERR(emc->pll_m)) {
-               err = PTR_ERR(emc->pll_m);
-               dev_err(&pdev->dev, "failed to get pll_m clock: %d\n", err);
-               return err;
-       }
-
-       emc->backup_clk = clk_get_sys(NULL, "pll_p");
-       if (IS_ERR(emc->backup_clk)) {
-               err = PTR_ERR(emc->backup_clk);
-               dev_err(&pdev->dev, "failed to get pll_p clock: %d\n", err);
-               goto put_pll_m;
-       }
-
-       emc->emc_mux = clk_get_parent(emc->clk);
-       if (IS_ERR(emc->emc_mux)) {
-               err = PTR_ERR(emc->emc_mux);
-               dev_err(&pdev->dev, "failed to get emc_mux clock: %d\n", err);
-               goto put_backup;
+               goto unset_cb;
        }
 
        err = clk_notifier_register(emc->clk, &emc->clk_nb);
        if (err) {
                dev_err(&pdev->dev, "failed to register clk notifier: %d\n",
                        err);
-               goto put_backup;
-       }
-
-       /* set DRAM clock rate to maximum */
-       err = emc_init(emc, emc->timings[emc->num_timings - 1].rate);
-       if (err) {
-               dev_err(&pdev->dev, "failed to initialize EMC clock rate: %d\n",
-                       err);
-               goto unreg_notifier;
+               goto unset_cb;
        }
 
        return 0;
 
-unreg_notifier:
-       clk_notifier_unregister(emc->clk, &emc->clk_nb);
-put_backup:
-       clk_put(emc->backup_clk);
-put_pll_m:
-       clk_put(emc->pll_m);
+unset_cb:
+       tegra20_clk_set_emc_round_callback(NULL, NULL);
 
        return err;
 }
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
new file mode 100644 (file)
index 0000000..0b6a5e4
--- /dev/null
@@ -0,0 +1,1232 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tegra30 External Memory Controller driver
+ *
+ * Based on downstream driver from NVIDIA and tegra124-emc.c
+ * Copyright (C) 2011-2014 NVIDIA Corporation
+ *
+ * Author: Dmitry Osipenko <digetx@gmail.com>
+ * Copyright (C) 2019 GRATE-DRIVER project
+ */
+
+#include <linux/clk.h>
+#include <linux/clk/tegra.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/sort.h>
+#include <linux/types.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "mc.h"
+
+#define EMC_INTSTATUS                          0x000
+#define EMC_INTMASK                            0x004
+#define EMC_DBG                                        0x008
+#define EMC_CFG                                        0x00c
+#define EMC_REFCTRL                            0x020
+#define EMC_TIMING_CONTROL                     0x028
+#define EMC_RC                                 0x02c
+#define EMC_RFC                                        0x030
+#define EMC_RAS                                        0x034
+#define EMC_RP                                 0x038
+#define EMC_R2W                                        0x03c
+#define EMC_W2R                                        0x040
+#define EMC_R2P                                        0x044
+#define EMC_W2P                                        0x048
+#define EMC_RD_RCD                             0x04c
+#define EMC_WR_RCD                             0x050
+#define EMC_RRD                                        0x054
+#define EMC_REXT                               0x058
+#define EMC_WDV                                        0x05c
+#define EMC_QUSE                               0x060
+#define EMC_QRST                               0x064
+#define EMC_QSAFE                              0x068
+#define EMC_RDV                                        0x06c
+#define EMC_REFRESH                            0x070
+#define EMC_BURST_REFRESH_NUM                  0x074
+#define EMC_PDEX2WR                            0x078
+#define EMC_PDEX2RD                            0x07c
+#define EMC_PCHG2PDEN                          0x080
+#define EMC_ACT2PDEN                           0x084
+#define EMC_AR2PDEN                            0x088
+#define EMC_RW2PDEN                            0x08c
+#define EMC_TXSR                               0x090
+#define EMC_TCKE                               0x094
+#define EMC_TFAW                               0x098
+#define EMC_TRPAB                              0x09c
+#define EMC_TCLKSTABLE                         0x0a0
+#define EMC_TCLKSTOP                           0x0a4
+#define EMC_TREFBW                             0x0a8
+#define EMC_QUSE_EXTRA                         0x0ac
+#define EMC_ODT_WRITE                          0x0b0
+#define EMC_ODT_READ                           0x0b4
+#define EMC_WEXT                               0x0b8
+#define EMC_CTT                                        0x0bc
+#define EMC_MRS_WAIT_CNT                       0x0c8
+#define EMC_MRS                                        0x0cc
+#define EMC_EMRS                               0x0d0
+#define EMC_SELF_REF                           0x0e0
+#define EMC_MRW                                        0x0e8
+#define EMC_XM2DQSPADCTRL3                     0x0f8
+#define EMC_FBIO_SPARE                         0x100
+#define EMC_FBIO_CFG5                          0x104
+#define EMC_FBIO_CFG6                          0x114
+#define EMC_CFG_RSV                            0x120
+#define EMC_AUTO_CAL_CONFIG                    0x2a4
+#define EMC_AUTO_CAL_INTERVAL                  0x2a8
+#define EMC_AUTO_CAL_STATUS                    0x2ac
+#define EMC_STATUS                             0x2b4
+#define EMC_CFG_2                              0x2b8
+#define EMC_CFG_DIG_DLL                                0x2bc
+#define EMC_CFG_DIG_DLL_PERIOD                 0x2c0
+#define EMC_CTT_DURATION                       0x2d8
+#define EMC_CTT_TERM_CTRL                      0x2dc
+#define EMC_ZCAL_INTERVAL                      0x2e0
+#define EMC_ZCAL_WAIT_CNT                      0x2e4
+#define EMC_ZQ_CAL                             0x2ec
+#define EMC_XM2CMDPADCTRL                      0x2f0
+#define EMC_XM2DQSPADCTRL2                     0x2fc
+#define EMC_XM2DQPADCTRL2                      0x304
+#define EMC_XM2CLKPADCTRL                      0x308
+#define EMC_XM2COMPPADCTRL                     0x30c
+#define EMC_XM2VTTGENPADCTRL                   0x310
+#define EMC_XM2VTTGENPADCTRL2                  0x314
+#define EMC_XM2QUSEPADCTRL                     0x318
+#define EMC_DLL_XFORM_DQS0                     0x328
+#define EMC_DLL_XFORM_DQS1                     0x32c
+#define EMC_DLL_XFORM_DQS2                     0x330
+#define EMC_DLL_XFORM_DQS3                     0x334
+#define EMC_DLL_XFORM_DQS4                     0x338
+#define EMC_DLL_XFORM_DQS5                     0x33c
+#define EMC_DLL_XFORM_DQS6                     0x340
+#define EMC_DLL_XFORM_DQS7                     0x344
+#define EMC_DLL_XFORM_QUSE0                    0x348
+#define EMC_DLL_XFORM_QUSE1                    0x34c
+#define EMC_DLL_XFORM_QUSE2                    0x350
+#define EMC_DLL_XFORM_QUSE3                    0x354
+#define EMC_DLL_XFORM_QUSE4                    0x358
+#define EMC_DLL_XFORM_QUSE5                    0x35c
+#define EMC_DLL_XFORM_QUSE6                    0x360
+#define EMC_DLL_XFORM_QUSE7                    0x364
+#define EMC_DLL_XFORM_DQ0                      0x368
+#define EMC_DLL_XFORM_DQ1                      0x36c
+#define EMC_DLL_XFORM_DQ2                      0x370
+#define EMC_DLL_XFORM_DQ3                      0x374
+#define EMC_DLI_TRIM_TXDQS0                    0x3a8
+#define EMC_DLI_TRIM_TXDQS1                    0x3ac
+#define EMC_DLI_TRIM_TXDQS2                    0x3b0
+#define EMC_DLI_TRIM_TXDQS3                    0x3b4
+#define EMC_DLI_TRIM_TXDQS4                    0x3b8
+#define EMC_DLI_TRIM_TXDQS5                    0x3bc
+#define EMC_DLI_TRIM_TXDQS6                    0x3c0
+#define EMC_DLI_TRIM_TXDQS7                    0x3c4
+#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE    0x3c8
+#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE     0x3cc
+#define EMC_UNSTALL_RW_AFTER_CLKCHANGE         0x3d0
+#define EMC_SEL_DPD_CTRL                       0x3d8
+#define EMC_PRE_REFRESH_REQ_CNT                        0x3dc
+#define EMC_DYN_SELF_REF_CONTROL               0x3e0
+#define EMC_TXSRDLL                            0x3e4
+
+#define EMC_STATUS_TIMING_UPDATE_STALLED       BIT(23)
+
+#define EMC_MODE_SET_DLL_RESET                 BIT(8)
+#define EMC_MODE_SET_LONG_CNT                  BIT(26)
+
+#define EMC_SELF_REF_CMD_ENABLED               BIT(0)
+
+#define DRAM_DEV_SEL_ALL                       (0 << 30)
+#define DRAM_DEV_SEL_0                         (2 << 30)
+#define DRAM_DEV_SEL_1                         (1 << 30)
+#define DRAM_BROADCAST(num) \
+       ((num) > 1 ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0)
+
+#define EMC_ZQ_CAL_CMD                         BIT(0)
+#define EMC_ZQ_CAL_LONG                                BIT(4)
+#define EMC_ZQ_CAL_LONG_CMD_DEV0 \
+       (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
+#define EMC_ZQ_CAL_LONG_CMD_DEV1 \
+       (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
+
+#define EMC_DBG_READ_MUX_ASSEMBLY              BIT(0)
+#define EMC_DBG_WRITE_MUX_ACTIVE               BIT(1)
+#define EMC_DBG_FORCE_UPDATE                   BIT(2)
+#define EMC_DBG_CFG_PRIORITY                   BIT(24)
+
+#define EMC_CFG5_QUSE_MODE_SHIFT               13
+#define EMC_CFG5_QUSE_MODE_MASK                        (7 << EMC_CFG5_QUSE_MODE_SHIFT)
+
+#define EMC_CFG5_QUSE_MODE_INTERNAL_LPBK       2
+#define EMC_CFG5_QUSE_MODE_PULSE_INTERN                3
+
+#define EMC_SEL_DPD_CTRL_QUSE_DPD_ENABLE       BIT(9)
+
+#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE     BIT(10)
+
+#define EMC_XM2QUSEPADCTRL_IVREF_ENABLE                BIT(4)
+
+#define EMC_XM2DQSPADCTRL2_VREF_ENABLE         BIT(5)
+#define EMC_XM2DQSPADCTRL3_VREF_ENABLE         BIT(5)
+
+#define EMC_AUTO_CAL_STATUS_ACTIVE             BIT(31)
+
+#define        EMC_FBIO_CFG5_DRAM_TYPE_MASK            0x3
+
+#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK       0x3ff
+#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT       16
+#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \
+       (0x3ff << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)
+
+#define EMC_REFCTRL_DEV_SEL_MASK               0x3
+#define EMC_REFCTRL_ENABLE                     BIT(31)
+#define EMC_REFCTRL_ENABLE_ALL(num) \
+       (((num) > 1 ? 0 : 2) | EMC_REFCTRL_ENABLE)
+#define EMC_REFCTRL_DISABLE_ALL(num)           ((num) > 1 ? 0 : 2)
+
+#define EMC_CFG_PERIODIC_QRST                  BIT(21)
+#define EMC_CFG_DYN_SREF_ENABLE                        BIT(28)
+
+#define EMC_CLKCHANGE_REQ_ENABLE               BIT(0)
+#define EMC_CLKCHANGE_PD_ENABLE                        BIT(1)
+#define EMC_CLKCHANGE_SR_ENABLE                        BIT(2)
+
+#define EMC_TIMING_UPDATE                      BIT(0)
+
+#define EMC_REFRESH_OVERFLOW_INT               BIT(3)
+#define EMC_CLKCHANGE_COMPLETE_INT             BIT(4)
+
+enum emc_dram_type {
+       DRAM_TYPE_DDR3,
+       DRAM_TYPE_DDR1,
+       DRAM_TYPE_LPDDR2,
+       DRAM_TYPE_DDR2,
+};
+
+enum emc_dll_change {
+       DLL_CHANGE_NONE,
+       DLL_CHANGE_ON,
+       DLL_CHANGE_OFF
+};
+
+static const u16 emc_timing_registers[] = {
+       [0] = EMC_RC,
+       [1] = EMC_RFC,
+       [2] = EMC_RAS,
+       [3] = EMC_RP,
+       [4] = EMC_R2W,
+       [5] = EMC_W2R,
+       [6] = EMC_R2P,
+       [7] = EMC_W2P,
+       [8] = EMC_RD_RCD,
+       [9] = EMC_WR_RCD,
+       [10] = EMC_RRD,
+       [11] = EMC_REXT,
+       [12] = EMC_WEXT,
+       [13] = EMC_WDV,
+       [14] = EMC_QUSE,
+       [15] = EMC_QRST,
+       [16] = EMC_QSAFE,
+       [17] = EMC_RDV,
+       [18] = EMC_REFRESH,
+       [19] = EMC_BURST_REFRESH_NUM,
+       [20] = EMC_PRE_REFRESH_REQ_CNT,
+       [21] = EMC_PDEX2WR,
+       [22] = EMC_PDEX2RD,
+       [23] = EMC_PCHG2PDEN,
+       [24] = EMC_ACT2PDEN,
+       [25] = EMC_AR2PDEN,
+       [26] = EMC_RW2PDEN,
+       [27] = EMC_TXSR,
+       [28] = EMC_TXSRDLL,
+       [29] = EMC_TCKE,
+       [30] = EMC_TFAW,
+       [31] = EMC_TRPAB,
+       [32] = EMC_TCLKSTABLE,
+       [33] = EMC_TCLKSTOP,
+       [34] = EMC_TREFBW,
+       [35] = EMC_QUSE_EXTRA,
+       [36] = EMC_FBIO_CFG6,
+       [37] = EMC_ODT_WRITE,
+       [38] = EMC_ODT_READ,
+       [39] = EMC_FBIO_CFG5,
+       [40] = EMC_CFG_DIG_DLL,
+       [41] = EMC_CFG_DIG_DLL_PERIOD,
+       [42] = EMC_DLL_XFORM_DQS0,
+       [43] = EMC_DLL_XFORM_DQS1,
+       [44] = EMC_DLL_XFORM_DQS2,
+       [45] = EMC_DLL_XFORM_DQS3,
+       [46] = EMC_DLL_XFORM_DQS4,
+       [47] = EMC_DLL_XFORM_DQS5,
+       [48] = EMC_DLL_XFORM_DQS6,
+       [49] = EMC_DLL_XFORM_DQS7,
+       [50] = EMC_DLL_XFORM_QUSE0,
+       [51] = EMC_DLL_XFORM_QUSE1,
+       [52] = EMC_DLL_XFORM_QUSE2,
+       [53] = EMC_DLL_XFORM_QUSE3,
+       [54] = EMC_DLL_XFORM_QUSE4,
+       [55] = EMC_DLL_XFORM_QUSE5,
+       [56] = EMC_DLL_XFORM_QUSE6,
+       [57] = EMC_DLL_XFORM_QUSE7,
+       [58] = EMC_DLI_TRIM_TXDQS0,
+       [59] = EMC_DLI_TRIM_TXDQS1,
+       [60] = EMC_DLI_TRIM_TXDQS2,
+       [61] = EMC_DLI_TRIM_TXDQS3,
+       [62] = EMC_DLI_TRIM_TXDQS4,
+       [63] = EMC_DLI_TRIM_TXDQS5,
+       [64] = EMC_DLI_TRIM_TXDQS6,
+       [65] = EMC_DLI_TRIM_TXDQS7,
+       [66] = EMC_DLL_XFORM_DQ0,
+       [67] = EMC_DLL_XFORM_DQ1,
+       [68] = EMC_DLL_XFORM_DQ2,
+       [69] = EMC_DLL_XFORM_DQ3,
+       [70] = EMC_XM2CMDPADCTRL,
+       [71] = EMC_XM2DQSPADCTRL2,
+       [72] = EMC_XM2DQPADCTRL2,
+       [73] = EMC_XM2CLKPADCTRL,
+       [74] = EMC_XM2COMPPADCTRL,
+       [75] = EMC_XM2VTTGENPADCTRL,
+       [76] = EMC_XM2VTTGENPADCTRL2,
+       [77] = EMC_XM2QUSEPADCTRL,
+       [78] = EMC_XM2DQSPADCTRL3,
+       [79] = EMC_CTT_TERM_CTRL,
+       [80] = EMC_ZCAL_INTERVAL,
+       [81] = EMC_ZCAL_WAIT_CNT,
+       [82] = EMC_MRS_WAIT_CNT,
+       [83] = EMC_AUTO_CAL_CONFIG,
+       [84] = EMC_CTT,
+       [85] = EMC_CTT_DURATION,
+       [86] = EMC_DYN_SELF_REF_CONTROL,
+       [87] = EMC_FBIO_SPARE,
+       [88] = EMC_CFG_RSV,
+};
+
+struct emc_timing {
+       unsigned long rate;
+
+       u32 data[ARRAY_SIZE(emc_timing_registers)];
+
+       u32 emc_auto_cal_interval;
+       u32 emc_mode_1;
+       u32 emc_mode_2;
+       u32 emc_mode_reset;
+       u32 emc_zcal_cnt_long;
+       bool emc_cfg_periodic_qrst;
+       bool emc_cfg_dyn_self_ref;
+};
+
+struct tegra_emc {
+       struct device *dev;
+       struct tegra_mc *mc;
+       struct completion clk_handshake_complete;
+       struct notifier_block clk_nb;
+       struct clk *clk;
+       void __iomem *regs;
+       unsigned int irq;
+
+       struct emc_timing *timings;
+       unsigned int num_timings;
+
+       u32 mc_override;
+       u32 emc_cfg;
+
+       u32 emc_mode_1;
+       u32 emc_mode_2;
+       u32 emc_mode_reset;
+
+       bool vref_cal_toggle : 1;
+       bool zcal_long : 1;
+       bool dll_on : 1;
+       bool prepared : 1;
+       bool bad_state : 1;
+};
+
+static irqreturn_t tegra_emc_isr(int irq, void *data)
+{
+       struct tegra_emc *emc = data;
+       u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
+       u32 status;
+
+       status = readl_relaxed(emc->regs + EMC_INTSTATUS) & intmask;
+       if (!status)
+               return IRQ_NONE;
+
+       /* notify about EMC-CAR handshake completion */
+       if (status & EMC_CLKCHANGE_COMPLETE_INT)
+               complete(&emc->clk_handshake_complete);
+
+       /* notify about HW problem */
+       if (status & EMC_REFRESH_OVERFLOW_INT)
+               dev_err_ratelimited(emc->dev,
+                                   "refresh request overflow timeout\n");
+
+       /* clear interrupts */
+       writel_relaxed(status, emc->regs + EMC_INTSTATUS);
+
+       return IRQ_HANDLED;
+}
+
+static struct emc_timing *emc_find_timing(struct tegra_emc *emc,
+                                         unsigned long rate)
+{
+       struct emc_timing *timing = NULL;
+       unsigned int i;
+
+       for (i = 0; i < emc->num_timings; i++) {
+               if (emc->timings[i].rate >= rate) {
+                       timing = &emc->timings[i];
+                       break;
+               }
+       }
+
+       if (!timing) {
+               dev_err(emc->dev, "no timing for rate %lu\n", rate);
+               return NULL;
+       }
+
+       return timing;
+}
+
+static bool emc_dqs_preset(struct tegra_emc *emc, struct emc_timing *timing,
+                          bool *schmitt_to_vref)
+{
+       bool preset = false;
+       u32 val;
+
+       if (timing->data[71] & EMC_XM2DQSPADCTRL2_VREF_ENABLE) {
+               val = readl_relaxed(emc->regs + EMC_XM2DQSPADCTRL2);
+
+               if (!(val & EMC_XM2DQSPADCTRL2_VREF_ENABLE)) {
+                       val |= EMC_XM2DQSPADCTRL2_VREF_ENABLE;
+                       writel_relaxed(val, emc->regs + EMC_XM2DQSPADCTRL2);
+
+                       preset = true;
+               }
+       }
+
+       if (timing->data[78] & EMC_XM2DQSPADCTRL3_VREF_ENABLE) {
+               val = readl_relaxed(emc->regs + EMC_XM2DQSPADCTRL3);
+
+               if (!(val & EMC_XM2DQSPADCTRL3_VREF_ENABLE)) {
+                       val |= EMC_XM2DQSPADCTRL3_VREF_ENABLE;
+                       writel_relaxed(val, emc->regs + EMC_XM2DQSPADCTRL3);
+
+                       preset = true;
+               }
+       }
+
+       if (timing->data[77] & EMC_XM2QUSEPADCTRL_IVREF_ENABLE) {
+               val = readl_relaxed(emc->regs + EMC_XM2QUSEPADCTRL);
+
+               if (!(val & EMC_XM2QUSEPADCTRL_IVREF_ENABLE)) {
+                       val |= EMC_XM2QUSEPADCTRL_IVREF_ENABLE;
+                       writel_relaxed(val, emc->regs + EMC_XM2QUSEPADCTRL);
+
+                       *schmitt_to_vref = true;
+                       preset = true;
+               }
+       }
+
+       return preset;
+}
+
+static int emc_seq_update_timing(struct tegra_emc *emc)
+{
+       u32 val;
+       int err;
+
+       writel_relaxed(EMC_TIMING_UPDATE, emc->regs + EMC_TIMING_CONTROL);
+
+       err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_STATUS, val,
+                               !(val & EMC_STATUS_TIMING_UPDATE_STALLED),
+                               1, 200);
+       if (err) {
+               dev_err(emc->dev, "failed to update timing: %d\n", err);
+               return err;
+       }
+
+       return 0;
+}
+
+static int emc_prepare_mc_clk_cfg(struct tegra_emc *emc, unsigned long rate)
+{
+       struct tegra_mc *mc = emc->mc;
+       unsigned int misc0_index = 16;
+       unsigned int i;
+       bool same;
+
+       for (i = 0; i < mc->num_timings; i++) {
+               if (mc->timings[i].rate != rate)
+                       continue;
+
+               if (mc->timings[i].emem_data[misc0_index] & BIT(27))
+                       same = true;
+               else
+                       same = false;
+
+               return tegra20_clk_prepare_emc_mc_same_freq(emc->clk, same);
+       }
+
+       return -EINVAL;
+}
+
+static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
+{
+       struct emc_timing *timing = emc_find_timing(emc, rate);
+       enum emc_dll_change dll_change;
+       enum emc_dram_type dram_type;
+       bool schmitt_to_vref = false;
+       unsigned int pre_wait = 0;
+       bool qrst_used = false;
+       unsigned int dram_num;
+       unsigned int i;
+       u32 fbio_cfg5;
+       u32 emc_dbg;
+       u32 val;
+       int err;
+
+       if (!timing || emc->bad_state)
+               return -EINVAL;
+
+       dev_dbg(emc->dev, "%s: using timing rate %lu for requested rate %lu\n",
+               __func__, timing->rate, rate);
+
+       emc->bad_state = true;
+
+       err = emc_prepare_mc_clk_cfg(emc, rate);
+       if (err) {
+               dev_err(emc->dev, "mc clock preparation failed: %d\n", err);
+               return err;
+       }
+
+       emc->vref_cal_toggle = false;
+       emc->mc_override = mc_readl(emc->mc, MC_EMEM_ARB_OVERRIDE);
+       emc->emc_cfg = readl_relaxed(emc->regs + EMC_CFG);
+       emc_dbg = readl_relaxed(emc->regs + EMC_DBG);
+
+       if (emc->dll_on == !!(timing->emc_mode_1 & 0x1))
+               dll_change = DLL_CHANGE_NONE;
+       else if (timing->emc_mode_1 & 0x1)
+               dll_change = DLL_CHANGE_ON;
+       else
+               dll_change = DLL_CHANGE_OFF;
+
+       emc->dll_on = !!(timing->emc_mode_1 & 0x1);
+
+       if (timing->data[80] && !readl_relaxed(emc->regs + EMC_ZCAL_INTERVAL))
+               emc->zcal_long = true;
+       else
+               emc->zcal_long = false;
+
+       fbio_cfg5 = readl_relaxed(emc->regs + EMC_FBIO_CFG5);
+       dram_type = fbio_cfg5 & EMC_FBIO_CFG5_DRAM_TYPE_MASK;
+
+       dram_num = tegra_mc_get_emem_device_count(emc->mc);
+
+       /* disable dynamic self-refresh */
+       if (emc->emc_cfg & EMC_CFG_DYN_SREF_ENABLE) {
+               emc->emc_cfg &= ~EMC_CFG_DYN_SREF_ENABLE;
+               writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG);
+
+               pre_wait = 5;
+       }
+
+       /* update MC arbiter settings */
+       val = mc_readl(emc->mc, MC_EMEM_ARB_OUTSTANDING_REQ);
+       if (!(val & MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE) ||
+           ((val & MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK) > 0x50)) {
+
+               val = MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE |
+                     MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE | 0x50;
+               mc_writel(emc->mc, val, MC_EMEM_ARB_OUTSTANDING_REQ);
+               mc_writel(emc->mc, MC_TIMING_UPDATE, MC_TIMING_CONTROL);
+       }
+
+       if (emc->mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK)
+               mc_writel(emc->mc,
+                         emc->mc_override & ~MC_EMEM_ARB_OVERRIDE_EACK_MASK,
+                         MC_EMEM_ARB_OVERRIDE);
+
+       /* check DQ/DQS VREF delay */
+       if (emc_dqs_preset(emc, timing, &schmitt_to_vref)) {
+               if (pre_wait < 3)
+                       pre_wait = 3;
+       }
+
+       if (pre_wait) {
+               err = emc_seq_update_timing(emc);
+               if (err)
+                       return err;
+
+               udelay(pre_wait);
+       }
+
+       /* disable auto-calibration if VREF mode is switching */
+       if (timing->emc_auto_cal_interval) {
+               val = readl_relaxed(emc->regs + EMC_XM2COMPPADCTRL);
+               val ^= timing->data[74];
+
+               if (val & EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE) {
+                       writel_relaxed(0, emc->regs + EMC_AUTO_CAL_INTERVAL);
+
+                       err = readl_relaxed_poll_timeout_atomic(
+                               emc->regs + EMC_AUTO_CAL_STATUS, val,
+                               !(val & EMC_AUTO_CAL_STATUS_ACTIVE), 1, 300);
+                       if (err) {
+                               dev_err(emc->dev,
+                                       "failed to disable auto-cal: %d\n",
+                                       err);
+                               return err;
+                       }
+
+                       emc->vref_cal_toggle = true;
+               }
+       }
+
+       /* program shadow registers */
+       for (i = 0; i < ARRAY_SIZE(timing->data); i++) {
+               /* EMC_XM2CLKPADCTRL should be programmed separately */
+               if (i != 73)
+                       writel_relaxed(timing->data[i],
+                                      emc->regs + emc_timing_registers[i]);
+       }
+
+       err = tegra_mc_write_emem_configuration(emc->mc, timing->rate);
+       if (err)
+               return err;
+
+       /* DDR3: predict MRS long wait count */
+       if (dram_type == DRAM_TYPE_DDR3 && dll_change == DLL_CHANGE_ON) {
+               u32 cnt = 512;
+
+               if (emc->zcal_long)
+                       cnt -= dram_num * 256;
+
+               val = timing->data[82] & EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK;
+               if (cnt < val)
+                       cnt = val;
+
+               val = timing->data[82] & ~EMC_MRS_WAIT_CNT_LONG_WAIT_MASK;
+               val |= (cnt << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT) &
+                       EMC_MRS_WAIT_CNT_LONG_WAIT_MASK;
+
+               writel_relaxed(val, emc->regs + EMC_MRS_WAIT_CNT);
+       }
+
+       /* disable interrupt since read access is prohibited after stalling */
+       disable_irq(emc->irq);
+
+       /* this read also completes the writes */
+       val = readl_relaxed(emc->regs + EMC_SEL_DPD_CTRL);
+
+       if (!(val & EMC_SEL_DPD_CTRL_QUSE_DPD_ENABLE) && schmitt_to_vref) {
+               u32 cur_mode, new_mode;
+
+               cur_mode = fbio_cfg5 & EMC_CFG5_QUSE_MODE_MASK;
+               cur_mode >>= EMC_CFG5_QUSE_MODE_SHIFT;
+
+               new_mode = timing->data[39] & EMC_CFG5_QUSE_MODE_MASK;
+               new_mode >>= EMC_CFG5_QUSE_MODE_SHIFT;
+
+               if ((cur_mode != EMC_CFG5_QUSE_MODE_PULSE_INTERN &&
+                    cur_mode != EMC_CFG5_QUSE_MODE_INTERNAL_LPBK) ||
+                   (new_mode != EMC_CFG5_QUSE_MODE_PULSE_INTERN &&
+                    new_mode != EMC_CFG5_QUSE_MODE_INTERNAL_LPBK))
+                       qrst_used = true;
+       }
+
+       /* flow control marker 1 */
+       writel_relaxed(0x1, emc->regs + EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE);
+
+       /* enable periodic reset */
+       if (qrst_used) {
+               writel_relaxed(emc_dbg | EMC_DBG_WRITE_MUX_ACTIVE,
+                              emc->regs + EMC_DBG);
+               writel_relaxed(emc->emc_cfg | EMC_CFG_PERIODIC_QRST,
+                              emc->regs + EMC_CFG);
+               writel_relaxed(emc_dbg, emc->regs + EMC_DBG);
+       }
+
+       /* disable auto-refresh to save time after clock change */
+       writel_relaxed(EMC_REFCTRL_DISABLE_ALL(dram_num),
+                      emc->regs + EMC_REFCTRL);
+
+       /* turn off DLL and enter self-refresh on DDR3 */
+       if (dram_type == DRAM_TYPE_DDR3) {
+               if (dll_change == DLL_CHANGE_OFF)
+                       writel_relaxed(timing->emc_mode_1,
+                                      emc->regs + EMC_EMRS);
+
+               writel_relaxed(DRAM_BROADCAST(dram_num) |
+                              EMC_SELF_REF_CMD_ENABLED,
+                              emc->regs + EMC_SELF_REF);
+       }
+
+       /* flow control marker 2 */
+       writel_relaxed(0x1, emc->regs + EMC_STALL_THEN_EXE_AFTER_CLKCHANGE);
+
+       /* enable write-active MUX, update unshadowed pad control */
+       writel_relaxed(emc_dbg | EMC_DBG_WRITE_MUX_ACTIVE, emc->regs + EMC_DBG);
+       writel_relaxed(timing->data[73], emc->regs + EMC_XM2CLKPADCTRL);
+
+       /* restore periodic QRST and disable write-active MUX */
+       val = !!(emc->emc_cfg & EMC_CFG_PERIODIC_QRST);
+       if (qrst_used || timing->emc_cfg_periodic_qrst != val) {
+               if (timing->emc_cfg_periodic_qrst)
+                       emc->emc_cfg |= EMC_CFG_PERIODIC_QRST;
+               else
+                       emc->emc_cfg &= ~EMC_CFG_PERIODIC_QRST;
+
+               writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG);
+       }
+       writel_relaxed(emc_dbg, emc->regs + EMC_DBG);
+
+       /* exit self-refresh on DDR3 */
+       if (dram_type == DRAM_TYPE_DDR3)
+               writel_relaxed(DRAM_BROADCAST(dram_num),
+                              emc->regs + EMC_SELF_REF);
+
+       /* set DRAM-mode registers */
+       if (dram_type == DRAM_TYPE_DDR3) {
+               if (timing->emc_mode_1 != emc->emc_mode_1)
+                       writel_relaxed(timing->emc_mode_1,
+                                      emc->regs + EMC_EMRS);
+
+               if (timing->emc_mode_2 != emc->emc_mode_2)
+                       writel_relaxed(timing->emc_mode_2,
+                                      emc->regs + EMC_EMRS);
+
+               if (timing->emc_mode_reset != emc->emc_mode_reset ||
+                   dll_change == DLL_CHANGE_ON) {
+                       val = timing->emc_mode_reset;
+                       if (dll_change == DLL_CHANGE_ON) {
+                               val |= EMC_MODE_SET_DLL_RESET;
+                               val |= EMC_MODE_SET_LONG_CNT;
+                       } else {
+                               val &= ~EMC_MODE_SET_DLL_RESET;
+                       }
+                       writel_relaxed(val, emc->regs + EMC_MRS);
+               }
+       } else {
+               if (timing->emc_mode_2 != emc->emc_mode_2)
+                       writel_relaxed(timing->emc_mode_2,
+                                      emc->regs + EMC_MRW);
+
+               if (timing->emc_mode_1 != emc->emc_mode_1)
+                       writel_relaxed(timing->emc_mode_1,
+                                      emc->regs + EMC_MRW);
+       }
+
+       emc->emc_mode_1 = timing->emc_mode_1;
+       emc->emc_mode_2 = timing->emc_mode_2;
+       emc->emc_mode_reset = timing->emc_mode_reset;
+
+       /* issue ZCAL command if turning ZCAL on */
+       if (emc->zcal_long) {
+               writel_relaxed(EMC_ZQ_CAL_LONG_CMD_DEV0,
+                              emc->regs + EMC_ZQ_CAL);
+
+               if (dram_num > 1)
+                       writel_relaxed(EMC_ZQ_CAL_LONG_CMD_DEV1,
+                                      emc->regs + EMC_ZQ_CAL);
+       }
+
+       /* re-enable auto-refresh */
+       writel_relaxed(EMC_REFCTRL_ENABLE_ALL(dram_num),
+                      emc->regs + EMC_REFCTRL);
+
+       /* flow control marker 3 */
+       writel_relaxed(0x1, emc->regs + EMC_UNSTALL_RW_AFTER_CLKCHANGE);
+
+       reinit_completion(&emc->clk_handshake_complete);
+
+       /* interrupt can be re-enabled now */
+       enable_irq(emc->irq);
+
+       emc->bad_state = false;
+       emc->prepared = true;
+
+       return 0;
+}
+
+static int emc_complete_timing_change(struct tegra_emc *emc,
+                                     unsigned long rate)
+{
+       struct emc_timing *timing = emc_find_timing(emc, rate);
+       unsigned long timeout;
+       int ret;
+
+       timeout = wait_for_completion_timeout(&emc->clk_handshake_complete,
+                                             msecs_to_jiffies(100));
+       if (timeout == 0) {
+               dev_err(emc->dev, "emc-car handshake failed\n");
+               emc->bad_state = true;
+               return -EIO;
+       }
+
+       /* restore auto-calibration */
+       if (emc->vref_cal_toggle)
+               writel_relaxed(timing->emc_auto_cal_interval,
+                              emc->regs + EMC_AUTO_CAL_INTERVAL);
+
+       /* restore dynamic self-refresh */
+       if (timing->emc_cfg_dyn_self_ref) {
+               emc->emc_cfg |= EMC_CFG_DYN_SREF_ENABLE;
+               writel_relaxed(emc->emc_cfg, emc->regs + EMC_CFG);
+       }
+
+       /* set number of clocks to wait after each ZQ command */
+       if (emc->zcal_long)
+               writel_relaxed(timing->emc_zcal_cnt_long,
+                              emc->regs + EMC_ZCAL_WAIT_CNT);
+
+       udelay(2);
+       /* update restored timing */
+       ret = emc_seq_update_timing(emc);
+       if (ret)
+               emc->bad_state = true;
+
+       /* restore early ACK */
+       mc_writel(emc->mc, emc->mc_override, MC_EMEM_ARB_OVERRIDE);
+
+       emc->prepared = false;
+
+       return ret;
+}
+
+static int emc_unprepare_timing_change(struct tegra_emc *emc,
+                                      unsigned long rate)
+{
+       if (emc->prepared && !emc->bad_state) {
+               /* shouldn't ever happen in practice */
+               dev_err(emc->dev, "timing configuration can't be reverted\n");
+               emc->bad_state = true;
+       }
+
+       return 0;
+}
+
+static int emc_clk_change_notify(struct notifier_block *nb,
+                                unsigned long msg, void *data)
+{
+       struct tegra_emc *emc = container_of(nb, struct tegra_emc, clk_nb);
+       struct clk_notifier_data *cnd = data;
+       int err;
+
+       switch (msg) {
+       case PRE_RATE_CHANGE:
+               err = emc_prepare_timing_change(emc, cnd->new_rate);
+               break;
+
+       case ABORT_RATE_CHANGE:
+               err = emc_unprepare_timing_change(emc, cnd->old_rate);
+               break;
+
+       case POST_RATE_CHANGE:
+               err = emc_complete_timing_change(emc, cnd->new_rate);
+               break;
+
+       default:
+               return NOTIFY_DONE;
+       }
+
+       return notifier_from_errno(err);
+}
+
+static int load_one_timing_from_dt(struct tegra_emc *emc,
+                                  struct emc_timing *timing,
+                                  struct device_node *node)
+{
+       u32 value;
+       int err;
+
+       err = of_property_read_u32(node, "clock-frequency", &value);
+       if (err) {
+               dev_err(emc->dev, "timing %pOF: failed to read rate: %d\n",
+                       node, err);
+               return err;
+       }
+
+       timing->rate = value;
+
+       err = of_property_read_u32_array(node, "nvidia,emc-configuration",
+                                        timing->data,
+                                        ARRAY_SIZE(emc_timing_registers));
+       if (err) {
+               dev_err(emc->dev,
+                       "timing %pOF: failed to read emc timing data: %d\n",
+                       node, err);
+               return err;
+       }
+
+#define EMC_READ_BOOL(prop, dtprop) \
+       timing->prop = of_property_read_bool(node, dtprop);
+
+#define EMC_READ_U32(prop, dtprop) \
+       err = of_property_read_u32(node, dtprop, &timing->prop); \
+       if (err) { \
+               dev_err(emc->dev, \
+                       "timing %pOFn: failed to read " #prop ": %d\n", \
+                       node, err); \
+               return err; \
+       }
+
+       EMC_READ_U32(emc_auto_cal_interval, "nvidia,emc-auto-cal-interval")
+       EMC_READ_U32(emc_mode_1, "nvidia,emc-mode-1")
+       EMC_READ_U32(emc_mode_2, "nvidia,emc-mode-2")
+       EMC_READ_U32(emc_mode_reset, "nvidia,emc-mode-reset")
+       EMC_READ_U32(emc_zcal_cnt_long, "nvidia,emc-zcal-cnt-long")
+       EMC_READ_BOOL(emc_cfg_dyn_self_ref, "nvidia,emc-cfg-dyn-self-ref")
+       EMC_READ_BOOL(emc_cfg_periodic_qrst, "nvidia,emc-cfg-periodic-qrst")
+
+#undef EMC_READ_U32
+#undef EMC_READ_BOOL
+
+       dev_dbg(emc->dev, "%s: %pOF: rate %lu\n", __func__, node, timing->rate);
+
+       return 0;
+}
+
+static int cmp_timings(const void *_a, const void *_b)
+{
+       const struct emc_timing *a = _a;
+       const struct emc_timing *b = _b;
+
+       if (a->rate < b->rate)
+               return -1;
+
+       if (a->rate > b->rate)
+               return 1;
+
+       return 0;
+}
+
+static int emc_check_mc_timings(struct tegra_emc *emc)
+{
+       struct tegra_mc *mc = emc->mc;
+       unsigned int i;
+
+       if (emc->num_timings != mc->num_timings) {
+               dev_err(emc->dev, "emc/mc timings number mismatch: %u %u\n",
+                       emc->num_timings, mc->num_timings);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < mc->num_timings; i++) {
+               if (emc->timings[i].rate != mc->timings[i].rate) {
+                       dev_err(emc->dev,
+                               "emc/mc timing rate mismatch: %lu %lu\n",
+                               emc->timings[i].rate, mc->timings[i].rate);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int emc_load_timings_from_dt(struct tegra_emc *emc,
+                                   struct device_node *node)
+{
+       struct device_node *child;
+       struct emc_timing *timing;
+       int child_count;
+       int err;
+
+       child_count = of_get_child_count(node);
+       if (!child_count) {
+               dev_err(emc->dev, "no memory timings in: %pOF\n", node);
+               return -EINVAL;
+       }
+
+       emc->timings = devm_kcalloc(emc->dev, child_count, sizeof(*timing),
+                                   GFP_KERNEL);
+       if (!emc->timings)
+               return -ENOMEM;
+
+       emc->num_timings = child_count;
+       timing = emc->timings;
+
+       for_each_child_of_node(node, child) {
+               err = load_one_timing_from_dt(emc, timing++, child);
+               if (err) {
+                       of_node_put(child);
+                       return err;
+               }
+       }
+
+       sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings,
+            NULL);
+
+       err = emc_check_mc_timings(emc);
+       if (err)
+               return err;
+
+       dev_info(emc->dev,
+                "got %u timings for RAM code %u (min %luMHz max %luMHz)\n",
+                emc->num_timings,
+                tegra_read_ram_code(),
+                emc->timings[0].rate / 1000000,
+                emc->timings[emc->num_timings - 1].rate / 1000000);
+
+       return 0;
+}
+
+static struct device_node *emc_find_node_by_ram_code(struct device *dev)
+{
+       struct device_node *np;
+       u32 value, ram_code;
+       int err;
+
+       ram_code = tegra_read_ram_code();
+
+       for_each_child_of_node(dev->of_node, np) {
+               err = of_property_read_u32(np, "nvidia,ram-code", &value);
+               if (err || value != ram_code)
+                       continue;
+
+               return np;
+       }
+
+       dev_err(dev, "no memory timings for RAM code %u found in device-tree\n",
+               ram_code);
+
+       return NULL;
+}
+
+static int emc_setup_hw(struct tegra_emc *emc)
+{
+       u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
+       u32 fbio_cfg5, emc_cfg, emc_dbg;
+       enum emc_dram_type dram_type;
+
+       fbio_cfg5 = readl_relaxed(emc->regs + EMC_FBIO_CFG5);
+       dram_type = fbio_cfg5 & EMC_FBIO_CFG5_DRAM_TYPE_MASK;
+
+       emc_cfg = readl_relaxed(emc->regs + EMC_CFG_2);
+
+       /* enable EMC and CAR to handshake on PLL divider/source changes */
+       emc_cfg |= EMC_CLKCHANGE_REQ_ENABLE;
+
+       /* configure clock change mode accordingly to DRAM type */
+       switch (dram_type) {
+       case DRAM_TYPE_LPDDR2:
+               emc_cfg |= EMC_CLKCHANGE_PD_ENABLE;
+               emc_cfg &= ~EMC_CLKCHANGE_SR_ENABLE;
+               break;
+
+       default:
+               emc_cfg &= ~EMC_CLKCHANGE_SR_ENABLE;
+               emc_cfg &= ~EMC_CLKCHANGE_PD_ENABLE;
+               break;
+       }
+
+       writel_relaxed(emc_cfg, emc->regs + EMC_CFG_2);
+
+       /* initialize interrupt */
+       writel_relaxed(intmask, emc->regs + EMC_INTMASK);
+       writel_relaxed(0xffffffff, emc->regs + EMC_INTSTATUS);
+
+       /* ensure that unwanted debug features are disabled */
+       emc_dbg = readl_relaxed(emc->regs + EMC_DBG);
+       emc_dbg |= EMC_DBG_CFG_PRIORITY;
+       emc_dbg &= ~EMC_DBG_READ_MUX_ASSEMBLY;
+       emc_dbg &= ~EMC_DBG_WRITE_MUX_ACTIVE;
+       emc_dbg &= ~EMC_DBG_FORCE_UPDATE;
+       writel_relaxed(emc_dbg, emc->regs + EMC_DBG);
+
+       return 0;
+}
+
+static long emc_round_rate(unsigned long rate,
+                          unsigned long min_rate,
+                          unsigned long max_rate,
+                          void *arg)
+{
+       struct emc_timing *timing = NULL;
+       struct tegra_emc *emc = arg;
+       unsigned int i;
+
+       min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
+
+       for (i = 0; i < emc->num_timings; i++) {
+               if (emc->timings[i].rate < rate && i != emc->num_timings - 1)
+                       continue;
+
+               if (emc->timings[i].rate > max_rate) {
+                       i = max(i, 1u) - 1;
+
+                       if (emc->timings[i].rate < min_rate)
+                               break;
+               }
+
+               if (emc->timings[i].rate < min_rate)
+                       continue;
+
+               timing = &emc->timings[i];
+               break;
+       }
+
+       if (!timing) {
+               dev_err(emc->dev, "no timing for rate %lu min %lu max %lu\n",
+                       rate, min_rate, max_rate);
+               return -EINVAL;
+       }
+
+       return timing->rate;
+}
+
+static int tegra_emc_probe(struct platform_device *pdev)
+{
+       struct platform_device *mc;
+       struct device_node *np;
+       struct tegra_emc *emc;
+       int err;
+
+       if (of_get_child_count(pdev->dev.of_node) == 0) {
+               dev_info(&pdev->dev,
+                        "device-tree node doesn't have memory timings\n");
+               return -ENODEV;
+       }
+
+       np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
+       if (!np) {
+               dev_err(&pdev->dev, "could not get memory controller node\n");
+               return -ENOENT;
+       }
+
+       mc = of_find_device_by_node(np);
+       of_node_put(np);
+       if (!mc)
+               return -ENOENT;
+
+       np = emc_find_node_by_ram_code(&pdev->dev);
+       if (!np)
+               return -EINVAL;
+
+       emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
+       if (!emc) {
+               of_node_put(np);
+               return -ENOMEM;
+       }
+
+       emc->mc = platform_get_drvdata(mc);
+       if (!emc->mc)
+               return -EPROBE_DEFER;
+
+       init_completion(&emc->clk_handshake_complete);
+       emc->clk_nb.notifier_call = emc_clk_change_notify;
+       emc->dev = &pdev->dev;
+
+       err = emc_load_timings_from_dt(emc, np);
+       of_node_put(np);
+       if (err)
+               return err;
+
+       emc->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(emc->regs))
+               return PTR_ERR(emc->regs);
+
+       err = emc_setup_hw(emc);
+       if (err)
+               return err;
+
+       err = platform_get_irq(pdev, 0);
+       if (err < 0) {
+               dev_err(&pdev->dev, "interrupt not specified: %d\n", err);
+               return err;
+       }
+       emc->irq = err;
+
+       err = devm_request_irq(&pdev->dev, emc->irq, tegra_emc_isr, 0,
+                              dev_name(&pdev->dev), emc);
+       if (err) {
+               dev_err(&pdev->dev, "failed to request irq: %d\n", err);
+               return err;
+       }
+
+       tegra20_clk_set_emc_round_callback(emc_round_rate, emc);
+
+       emc->clk = devm_clk_get(&pdev->dev, "emc");
+       if (IS_ERR(emc->clk)) {
+               err = PTR_ERR(emc->clk);
+               dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
+               goto unset_cb;
+       }
+
+       err = clk_notifier_register(emc->clk, &emc->clk_nb);
+       if (err) {
+               dev_err(&pdev->dev, "failed to register clk notifier: %d\n",
+                       err);
+               goto unset_cb;
+       }
+
+       platform_set_drvdata(pdev, emc);
+
+       return 0;
+
+unset_cb:
+       tegra20_clk_set_emc_round_callback(NULL, NULL);
+
+       return err;
+}
+
+static int tegra_emc_suspend(struct device *dev)
+{
+       struct tegra_emc *emc = dev_get_drvdata(dev);
+
+       /*
+        * Suspending in a bad state will hang machine. The "prepared" var
+        * shall be always false here unless it's a kernel bug that caused
+        * suspending in a wrong order.
+        */
+       if (WARN_ON(emc->prepared) || emc->bad_state)
+               return -EINVAL;
+
+       emc->bad_state = true;
+
+       return 0;
+}
+
+static int tegra_emc_resume(struct device *dev)
+{
+       struct tegra_emc *emc = dev_get_drvdata(dev);
+
+       emc_setup_hw(emc);
+       emc->bad_state = false;
+
+       return 0;
+}
+
+static const struct dev_pm_ops tegra_emc_pm_ops = {
+       .suspend = tegra_emc_suspend,
+       .resume = tegra_emc_resume,
+};
+
+static const struct of_device_id tegra_emc_of_match[] = {
+       { .compatible = "nvidia,tegra30-emc", },
+       {},
+};
+
+static struct platform_driver tegra_emc_driver = {
+       .probe = tegra_emc_probe,
+       .driver = {
+               .name = "tegra30-emc",
+               .of_match_table = tegra_emc_of_match,
+               .pm = &tegra_emc_pm_ops,
+               .suppress_bind_attrs = true,
+       },
+};
+
+static int __init tegra_emc_init(void)
+{
+       return platform_driver_register(&tegra_emc_driver);
+}
+subsys_initcall(tegra_emc_init);
index 14788fc..fcdd812 100644 (file)
 
 #include "mc.h"
 
+static const unsigned long tegra30_mc_emem_regs[] = {
+       MC_EMEM_ARB_CFG,
+       MC_EMEM_ARB_OUTSTANDING_REQ,
+       MC_EMEM_ARB_TIMING_RCD,
+       MC_EMEM_ARB_TIMING_RP,
+       MC_EMEM_ARB_TIMING_RC,
+       MC_EMEM_ARB_TIMING_RAS,
+       MC_EMEM_ARB_TIMING_FAW,
+       MC_EMEM_ARB_TIMING_RRD,
+       MC_EMEM_ARB_TIMING_RAP2PRE,
+       MC_EMEM_ARB_TIMING_WAP2PRE,
+       MC_EMEM_ARB_TIMING_R2R,
+       MC_EMEM_ARB_TIMING_W2W,
+       MC_EMEM_ARB_TIMING_R2W,
+       MC_EMEM_ARB_TIMING_W2R,
+       MC_EMEM_ARB_DA_TURNS,
+       MC_EMEM_ARB_DA_COVERS,
+       MC_EMEM_ARB_MISC0,
+       MC_EMEM_ARB_RING1_THROTTLE,
+};
+
 static const struct tegra_mc_client tegra30_mc_clients[] = {
        {
                .id = 0x00,
@@ -931,16 +952,19 @@ static const struct tegra_smmu_swgroup tegra30_swgroups[] = {
        { .name = "isp",  .swgroup = TEGRA_SWGROUP_ISP,  .reg = 0x258 },
 };
 
-static const unsigned int tegra30_group_display[] = {
+static const unsigned int tegra30_group_drm[] = {
        TEGRA_SWGROUP_DC,
        TEGRA_SWGROUP_DCB,
+       TEGRA_SWGROUP_G2,
+       TEGRA_SWGROUP_NV,
+       TEGRA_SWGROUP_NV2,
 };
 
 static const struct tegra_smmu_group_soc tegra30_groups[] = {
        {
-               .name = "display",
-               .swgroups = tegra30_group_display,
-               .num_swgroups = ARRAY_SIZE(tegra30_group_display),
+               .name = "drm",
+               .swgroups = tegra30_group_drm,
+               .num_swgroups = ARRAY_SIZE(tegra30_group_drm),
        },
 };
 
@@ -994,6 +1018,8 @@ const struct tegra_mc_soc tegra30_mc_soc = {
        .atom_size = 16,
        .client_id_mask = 0x7f,
        .smmu = &tegra30_smmu_soc,
+       .emem_regs = tegra30_mc_emem_regs,
+       .num_emem_regs = ARRAY_SIZE(tegra30_mc_emem_regs),
        .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
                   MC_INT_DECERR_EMEM,
        .reset_ops = &tegra_mc_reset_ops_common,
index 426ad91..d054e28 100644 (file)
@@ -96,7 +96,7 @@ void *sram_exec_copy(struct gen_pool *pool, void *dst, void *src,
        if (!part)
                return NULL;
 
-       if (!addr_in_gen_pool(pool, (unsigned long)dst, size))
+       if (!gen_pool_has_addr(pool, (unsigned long)dst, size))
                return NULL;
 
        base = (unsigned long)part->base;
index 0a9f42e..2e57122 100644 (file)
@@ -617,6 +617,7 @@ err_free_chan:
        sl->tty = NULL;
        tty->disc_data = NULL;
        clear_bit(SLF_INUSE, &sl->flags);
+       slc_free_netdev(sl->dev);
        free_netdev(sl->dev);
 
 err_exit:
index 04aac3b..81e942f 100644 (file)
@@ -792,7 +792,7 @@ resubmit:
                          up);
 
        usb_anchor_urb(urb, &up->rx_urbs);
-       ret = usb_submit_urb(urb, GFP_KERNEL);
+       ret = usb_submit_urb(urb, GFP_ATOMIC);
 
        if (ret < 0) {
                netdev_err(up->netdev,
index 4a96e2d..464af93 100644 (file)
@@ -542,16 +542,17 @@ static int xcan_do_set_mode(struct net_device *ndev, enum can_mode mode)
 
 /**
  * xcan_write_frame - Write a frame to HW
- * @priv:              Driver private data structure
+ * @ndev:              Pointer to net_device structure
  * @skb:               sk_buff pointer that contains data to be Txed
  * @frame_offset:      Register offset to write the frame to
  */
-static void xcan_write_frame(struct xcan_priv *priv, struct sk_buff *skb,
+static void xcan_write_frame(struct net_device *ndev, struct sk_buff *skb,
                             int frame_offset)
 {
        u32 id, dlc, data[2] = {0, 0};
        struct canfd_frame *cf = (struct canfd_frame *)skb->data;
        u32 ramoff, dwindex = 0, i;
+       struct xcan_priv *priv = netdev_priv(ndev);
 
        /* Watch carefully on the bit sequence */
        if (cf->can_id & CAN_EFF_FLAG) {
@@ -587,6 +588,14 @@ static void xcan_write_frame(struct xcan_priv *priv, struct sk_buff *skb,
                dlc |= XCAN_DLCR_EDL_MASK;
        }
 
+       if (!(priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES) &&
+           (priv->devtype.flags & XCAN_FLAG_TXFEMP))
+               can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
+       else
+               can_put_echo_skb(skb, ndev, 0);
+
+       priv->tx_head++;
+
        priv->write_reg(priv, XCAN_FRAME_ID_OFFSET(frame_offset), id);
        /* If the CAN frame is RTR frame this write triggers transmission
         * (not on CAN FD)
@@ -638,13 +647,9 @@ static int xcan_start_xmit_fifo(struct sk_buff *skb, struct net_device *ndev)
                        XCAN_SR_TXFLL_MASK))
                return -ENOSPC;
 
-       can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
-
        spin_lock_irqsave(&priv->tx_lock, flags);
 
-       priv->tx_head++;
-
-       xcan_write_frame(priv, skb, XCAN_TXFIFO_OFFSET);
+       xcan_write_frame(ndev, skb, XCAN_TXFIFO_OFFSET);
 
        /* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */
        if (priv->tx_max > 1)
@@ -675,13 +680,9 @@ static int xcan_start_xmit_mailbox(struct sk_buff *skb, struct net_device *ndev)
                     BIT(XCAN_TX_MAILBOX_IDX)))
                return -ENOSPC;
 
-       can_put_echo_skb(skb, ndev, 0);
-
        spin_lock_irqsave(&priv->tx_lock, flags);
 
-       priv->tx_head++;
-
-       xcan_write_frame(priv, skb,
+       xcan_write_frame(ndev, skb,
                         XCAN_TXMSG_FRAME_OFFSET(XCAN_TX_MAILBOX_IDX));
 
        /* Mark buffer as ready for transmit */
@@ -1772,7 +1773,8 @@ static int xcan_probe(struct platform_device *pdev)
 
        priv->bus_clk = devm_clk_get(&pdev->dev, devtype->bus_clk_name);
        if (IS_ERR(priv->bus_clk)) {
-               dev_err(&pdev->dev, "bus clock not found\n");
+               if (PTR_ERR(priv->bus_clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "bus clock not found\n");
                ret = PTR_ERR(priv->bus_clk);
                goto err_free;
        }
index a880f10..8083173 100644 (file)
@@ -129,13 +129,13 @@ struct xgbe_stats {
 
 #define XGMAC_MMC_STAT(_string, _var)                          \
        { _string,                                              \
-         FIELD_SIZEOF(struct xgbe_mmc_stats, _var),            \
+         sizeof_field(struct xgbe_mmc_stats, _var),            \
          offsetof(struct xgbe_prv_data, mmc_stats._var),       \
        }
 
 #define XGMAC_EXT_STAT(_string, _var)                          \
        { _string,                                              \
-         FIELD_SIZEOF(struct xgbe_ext_stats, _var),            \
+         sizeof_field(struct xgbe_ext_stats, _var),            \
          offsetof(struct xgbe_prv_data, ext_stats._var),       \
        }
 
index 0cc2338..dfc7750 100644 (file)
@@ -205,11 +205,11 @@ static int __cvmx_bootmem_check_version(struct octeon_device *oct,
        major_version = (u32)__cvmx_bootmem_desc_get(
                        oct, oct->bootmem_desc_addr,
                        offsetof(struct cvmx_bootmem_desc, major_version),
-                       FIELD_SIZEOF(struct cvmx_bootmem_desc, major_version));
+                       sizeof_field(struct cvmx_bootmem_desc, major_version));
        minor_version = (u32)__cvmx_bootmem_desc_get(
                        oct, oct->bootmem_desc_addr,
                        offsetof(struct cvmx_bootmem_desc, minor_version),
-                       FIELD_SIZEOF(struct cvmx_bootmem_desc, minor_version));
+                       sizeof_field(struct cvmx_bootmem_desc, minor_version));
 
        dev_dbg(&oct->pci_dev->dev, "%s: major_version=%d\n", __func__,
                major_version);
@@ -237,13 +237,13 @@ static const struct cvmx_bootmem_named_block_desc
                                oct, named_addr,
                                offsetof(struct cvmx_bootmem_named_block_desc,
                                         base_addr),
-                               FIELD_SIZEOF(
+                               sizeof_field(
                                        struct cvmx_bootmem_named_block_desc,
                                        base_addr));
                desc->size = __cvmx_bootmem_desc_get(oct, named_addr,
                                offsetof(struct cvmx_bootmem_named_block_desc,
                                         size),
-                               FIELD_SIZEOF(
+                               sizeof_field(
                                        struct cvmx_bootmem_named_block_desc,
                                        size));
 
@@ -268,20 +268,20 @@ static u64 cvmx_bootmem_phy_named_block_find(struct octeon_device *oct,
                                        oct, oct->bootmem_desc_addr,
                                        offsetof(struct cvmx_bootmem_desc,
                                                 named_block_array_addr),
-                                       FIELD_SIZEOF(struct cvmx_bootmem_desc,
+                                       sizeof_field(struct cvmx_bootmem_desc,
                                                     named_block_array_addr));
                u32 num_blocks = (u32)__cvmx_bootmem_desc_get(
                                        oct, oct->bootmem_desc_addr,
                                        offsetof(struct cvmx_bootmem_desc,
                                                 nb_num_blocks),
-                                       FIELD_SIZEOF(struct cvmx_bootmem_desc,
+                                       sizeof_field(struct cvmx_bootmem_desc,
                                                     nb_num_blocks));
 
                u32 name_length = (u32)__cvmx_bootmem_desc_get(
                                        oct, oct->bootmem_desc_addr,
                                        offsetof(struct cvmx_bootmem_desc,
                                                 named_block_name_len),
-                                       FIELD_SIZEOF(struct cvmx_bootmem_desc,
+                                       sizeof_field(struct cvmx_bootmem_desc,
                                                     named_block_name_len));
 
                u64 named_addr = named_block_array_addr;
@@ -292,7 +292,7 @@ static u64 cvmx_bootmem_phy_named_block_find(struct octeon_device *oct,
                                         offsetof(
                                        struct cvmx_bootmem_named_block_desc,
                                        size),
-                                        FIELD_SIZEOF(
+                                        sizeof_field(
                                        struct cvmx_bootmem_named_block_desc,
                                        size));
 
index 1e09fdb..c4f6ec0 100644 (file)
@@ -1115,7 +1115,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
                                       phy_interface_mode(lmac->lmac_type)))
                        return -ENODEV;
 
-               phy_start_aneg(lmac->phydev);
+               phy_start(lmac->phydev);
                return 0;
        }
 
index 5bb5abf..022a54a 100644 (file)
@@ -23,7 +23,7 @@ struct be_ethtool_stat {
 };
 
 enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
-#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
+#define FIELDINFO(_struct, field) sizeof_field(_struct, field), \
                                        offsetof(_struct, field)
 #define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\
                                        FIELDINFO(struct be_tx_stats, field)
index 9db1b96..1773990 100644 (file)
@@ -1332,6 +1332,7 @@ static int enetc_phy_connect(struct net_device *ndev)
 {
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
        struct phy_device *phydev;
+       struct ethtool_eee edata;
 
        if (!priv->phy_node)
                return 0; /* phy-less mode */
@@ -1345,6 +1346,10 @@ static int enetc_phy_connect(struct net_device *ndev)
 
        phy_attached_info(phydev);
 
+       /* disable EEE autoneg, until ENETC driver supports it */
+       memset(&edata, 0, sizeof(struct ethtool_eee));
+       phy_ethtool_set_eee(phydev, &edata);
+
        return 0;
 }
 
index ba05368..69545dd 100644 (file)
@@ -1287,30 +1287,25 @@ static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size,
 }
 
 static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
-                                 struct sk_buff **out_skb)
+                                 struct net_device *netdev,
+                                 struct sk_buff *skb)
 {
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
        unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U];
-       struct sk_buff *skb = *out_skb;
        unsigned int bd_num;
 
        bd_num = hns3_tx_bd_num(skb, bd_size);
        if (unlikely(bd_num > HNS3_MAX_NON_TSO_BD_NUM)) {
-               struct sk_buff *new_skb;
-
                if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) &&
                    !hns3_skb_need_linearized(skb, bd_size, bd_num))
                        goto out;
 
-               /* manual split the send packet */
-               new_skb = skb_copy(skb, GFP_ATOMIC);
-               if (!new_skb)
+               if (__skb_linearize(skb))
                        return -ENOMEM;
-               dev_kfree_skb_any(skb);
-               *out_skb = new_skb;
 
-               bd_num = hns3_tx_bd_count(new_skb->len);
-               if ((skb_is_gso(new_skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
-                   (!skb_is_gso(new_skb) &&
+               bd_num = hns3_tx_bd_count(skb->len);
+               if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
+                   (!skb_is_gso(skb) &&
                     bd_num > HNS3_MAX_NON_TSO_BD_NUM))
                        return -ENOMEM;
 
@@ -1320,10 +1315,23 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
        }
 
 out:
-       if (unlikely(ring_space(ring) < bd_num))
-               return -EBUSY;
+       if (likely(ring_space(ring) >= bd_num))
+               return bd_num;
 
-       return bd_num;
+       netif_stop_subqueue(netdev, ring->queue_index);
+       smp_mb(); /* Memory barrier before checking ring_space */
+
+       /* Start queue in case hns3_clean_tx_ring has just made room
+        * available and has not seen the queue stopped state performed
+        * by netif_stop_subqueue above.
+        */
+       if (ring_space(ring) >= bd_num && netif_carrier_ok(netdev) &&
+           !test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) {
+               netif_start_subqueue(netdev, ring->queue_index);
+               return bd_num;
+       }
+
+       return -EBUSY;
 }
 
 static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
@@ -1400,13 +1408,13 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
        /* Prefetch the data used later */
        prefetch(skb->data);
 
-       ret = hns3_nic_maybe_stop_tx(ring, &skb);
+       ret = hns3_nic_maybe_stop_tx(ring, netdev, skb);
        if (unlikely(ret <= 0)) {
                if (ret == -EBUSY) {
                        u64_stats_update_begin(&ring->syncp);
                        ring->stats.tx_busy++;
                        u64_stats_update_end(&ring->syncp);
-                       goto out_net_tx_busy;
+                       return NETDEV_TX_BUSY;
                } else if (ret == -ENOMEM) {
                        u64_stats_update_begin(&ring->syncp);
                        ring->stats.sw_err_cnt++;
@@ -1457,12 +1465,6 @@ fill_err:
 out_err_tx_ok:
        dev_kfree_skb_any(skb);
        return NETDEV_TX_OK;
-
-out_net_tx_busy:
-       netif_stop_subqueue(netdev, ring->queue_index);
-       smp_mb(); /* Commit all data before submit */
-
-       return NETDEV_TX_BUSY;
 }
 
 static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p)
@@ -2519,7 +2521,7 @@ void hns3_clean_tx_ring(struct hns3_enet_ring *ring)
        dev_queue = netdev_get_tx_queue(netdev, ring->tqp->tqp_index);
        netdev_tx_completed_queue(dev_queue, pkts, bytes);
 
-       if (unlikely(pkts && netif_carrier_ok(netdev) &&
+       if (unlikely(netif_carrier_ok(netdev) &&
                     ring_space(ring) > HNS3_MAX_TSO_BD_NUM)) {
                /* Make sure that anybody stopping the queue after this
                 * sees the new next_to_clean.
index 7c70386..13dbd24 100644 (file)
@@ -8438,13 +8438,16 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
        if (hdev->pdev->revision == 0x20)
                return -EOPNOTSUPP;
 
+       vport = hclge_get_vf_vport(hdev, vfid);
+       if (!vport)
+               return -EINVAL;
+
        /* qos is a 3 bits value, so can not be bigger than 7 */
-       if (vfid >= hdev->num_alloc_vfs || vlan > VLAN_N_VID - 1 || qos > 7)
+       if (vlan > VLAN_N_VID - 1 || qos > 7)
                return -EINVAL;
        if (proto != htons(ETH_P_8021Q))
                return -EPROTONOSUPPORT;
 
-       vport = &hdev->vport[vfid];
        state = hclge_get_port_base_vlan_state(vport,
                                               vport->port_base_vlan_cfg.state,
                                               vlan);
@@ -8455,21 +8458,12 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
        vlan_info.qos = qos;
        vlan_info.vlan_proto = ntohs(proto);
 
-       /* update port based VLAN for PF */
-       if (!vfid) {
-               hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
-               ret = hclge_update_port_base_vlan_cfg(vport, state, &vlan_info);
-               hclge_notify_client(hdev, HNAE3_UP_CLIENT);
-
-               return ret;
-       }
-
        if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
                return hclge_update_port_base_vlan_cfg(vport, state,
                                                       &vlan_info);
        } else {
                ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
-                                                       (u8)vfid, state,
+                                                       vport->vport_id, state,
                                                        vlan, qos,
                                                        ntohs(proto));
                return ret;
@@ -10246,7 +10240,7 @@ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
                return ret;
        }
 
-       data_len_per_desc = FIELD_SIZEOF(struct hclge_desc, data);
+       data_len_per_desc = sizeof_field(struct hclge_desc, data);
        *len = 0;
        for (i = 0; i < dfx_reg_type_num; i++) {
                bd_num = bd_num_list[i];
index fbc39a2..180224e 100644 (file)
@@ -614,7 +614,7 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
        }
 
        memcpy(kinfo->prio_tc, hdev->tm_info.prio_tc,
-              FIELD_SIZEOF(struct hnae3_knic_private_info, prio_tc));
+              sizeof_field(struct hnae3_knic_private_info, prio_tc));
 }
 
 static void hclge_tm_vport_info_update(struct hclge_dev *hdev)
index 60ec48f..966aea9 100644 (file)
@@ -450,7 +450,7 @@ static u32 hinic_get_rxfh_indir_size(struct net_device *netdev)
 
 #define HINIC_FUNC_STAT(_stat_item) {  \
        .name = #_stat_item, \
-       .size = FIELD_SIZEOF(struct hinic_vport_stats, _stat_item), \
+       .size = sizeof_field(struct hinic_vport_stats, _stat_item), \
        .offset = offsetof(struct hinic_vport_stats, _stat_item) \
 }
 
@@ -477,7 +477,7 @@ static struct hinic_stats hinic_function_stats[] = {
 
 #define HINIC_PORT_STAT(_stat_item) { \
        .name = #_stat_item, \
-       .size = FIELD_SIZEOF(struct hinic_phy_port_stats, _stat_item), \
+       .size = sizeof_field(struct hinic_phy_port_stats, _stat_item), \
        .offset = offsetof(struct hinic_phy_port_stats, _stat_item) \
 }
 
@@ -571,7 +571,7 @@ static struct hinic_stats hinic_port_stats[] = {
 
 #define HINIC_TXQ_STAT(_stat_item) { \
        .name = "txq%d_"#_stat_item, \
-       .size = FIELD_SIZEOF(struct hinic_txq_stats, _stat_item), \
+       .size = sizeof_field(struct hinic_txq_stats, _stat_item), \
        .offset = offsetof(struct hinic_txq_stats, _stat_item) \
 }
 
@@ -586,7 +586,7 @@ static struct hinic_stats hinic_tx_queue_stats[] = {
 
 #define HINIC_RXQ_STAT(_stat_item) { \
        .name = "rxq%d_"#_stat_item, \
-       .size = FIELD_SIZEOF(struct hinic_rxq_stats, _stat_item), \
+       .size = sizeof_field(struct hinic_rxq_stats, _stat_item), \
        .offset = offsetof(struct hinic_rxq_stats, _stat_item) \
 }
 
index c681d2d..68edf55 100644 (file)
@@ -18,7 +18,7 @@ struct fm10k_stats {
 
 #define FM10K_STAT_FIELDS(_type, _name, _stat) { \
        .stat_string = _name, \
-       .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
+       .sizeof_stat = sizeof_field(_type, _stat), \
        .stat_offset = offsetof(_type, _stat) \
 }
 
index d24d873..317f3f1 100644 (file)
@@ -43,7 +43,7 @@ struct i40e_stats {
  */
 #define I40E_STAT(_type, _name, _stat) { \
        .stat_string = _name, \
-       .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
+       .sizeof_stat = sizeof_field(_type, _stat), \
        .stat_offset = offsetof(_type, _stat) \
 }
 
index be24d42..a3da422 100644 (file)
@@ -659,7 +659,7 @@ i40e_status i40e_shutdown_lan_hmc(struct i40e_hw *hw)
 
 #define I40E_HMC_STORE(_struct, _ele)          \
        offsetof(struct _struct, _ele),         \
-       FIELD_SIZEOF(struct _struct, _ele)
+       sizeof_field(struct _struct, _ele)
 
 struct i40e_context_ele {
        u16 offset;
index dad3eec..84c3d8d 100644 (file)
@@ -42,7 +42,7 @@ struct iavf_stats {
  */
 #define IAVF_STAT(_type, _name, _stat) { \
        .stat_string = _name, \
-       .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
+       .sizeof_stat = sizeof_field(_type, _stat), \
        .stat_offset = offsetof(_type, _stat) \
 }
 
index aec3c6c..9ebd93e 100644 (file)
@@ -15,7 +15,7 @@ struct ice_stats {
 
 #define ICE_STAT(_type, _name, _stat) { \
        .stat_string = _name, \
-       .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
+       .sizeof_stat = sizeof_field(_type, _stat), \
        .stat_offset = offsetof(_type, _stat) \
 }
 
@@ -36,10 +36,10 @@ static int ice_q_stats_len(struct net_device *netdev)
 #define ICE_VSI_STATS_LEN      ARRAY_SIZE(ice_gstrings_vsi_stats)
 
 #define ICE_PFC_STATS_LEN ( \
-               (FIELD_SIZEOF(struct ice_pf, stats.priority_xoff_rx) + \
-                FIELD_SIZEOF(struct ice_pf, stats.priority_xon_rx) + \
-                FIELD_SIZEOF(struct ice_pf, stats.priority_xoff_tx) + \
-                FIELD_SIZEOF(struct ice_pf, stats.priority_xon_tx)) \
+               (sizeof_field(struct ice_pf, stats.priority_xoff_rx) + \
+                sizeof_field(struct ice_pf, stats.priority_xon_rx) + \
+                sizeof_field(struct ice_pf, stats.priority_xoff_tx) + \
+                sizeof_field(struct ice_pf, stats.priority_xon_tx)) \
                 / sizeof(u64))
 #define ICE_ALL_STATS_LEN(n)   (ICE_PF_STATS_LEN + ICE_PFC_STATS_LEN + \
                                 ICE_VSI_STATS_LEN + ice_q_stats_len(n))
index ad34f22..0997d35 100644 (file)
@@ -302,7 +302,7 @@ struct ice_ctx_ele {
 
 #define ICE_CTX_STORE(_struct, _ele, _width, _lsb) {   \
        .offset = offsetof(struct _struct, _ele),       \
-       .size_of = FIELD_SIZEOF(struct _struct, _ele),  \
+       .size_of = sizeof_field(struct _struct, _ele),  \
        .width = _width,                                \
        .lsb = _lsb,                                    \
 }
index 3182b05..4690d6c 100644 (file)
@@ -26,7 +26,7 @@ struct igb_stats {
 
 #define IGB_STAT(_name, _stat) { \
        .stat_string = _name, \
-       .sizeof_stat = FIELD_SIZEOF(struct igb_adapter, _stat), \
+       .sizeof_stat = sizeof_field(struct igb_adapter, _stat), \
        .stat_offset = offsetof(struct igb_adapter, _stat) \
 }
 static const struct igb_stats igb_gstrings_stats[] = {
@@ -76,7 +76,7 @@ static const struct igb_stats igb_gstrings_stats[] = {
 
 #define IGB_NETDEV_STAT(_net_stat) { \
        .stat_string = __stringify(_net_stat), \
-       .sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \
+       .sizeof_stat = sizeof_field(struct rtnl_link_stats64, _net_stat), \
        .stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \
 }
 static const struct igb_stats igb_gstrings_net_stats[] = {
index ac98f1d..455c1cd 100644 (file)
@@ -16,7 +16,7 @@ struct igc_stats {
 
 #define IGC_STAT(_name, _stat) { \
        .stat_string = _name, \
-       .sizeof_stat = FIELD_SIZEOF(struct igc_adapter, _stat), \
+       .sizeof_stat = sizeof_field(struct igc_adapter, _stat), \
        .stat_offset = offsetof(struct igc_adapter, _stat) \
 }
 
@@ -67,7 +67,7 @@ static const struct igc_stats igc_gstrings_stats[] = {
 
 #define IGC_NETDEV_STAT(_net_stat) { \
        .stat_string = __stringify(_net_stat), \
-       .sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \
+       .sizeof_stat = sizeof_field(struct rtnl_link_stats64, _net_stat), \
        .stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \
 }
 
index c8c93ac..c65eb1a 100644 (file)
@@ -19,10 +19,10 @@ struct ixgb_stats {
 };
 
 #define IXGB_STAT(m)           IXGB_STATS, \
-                               FIELD_SIZEOF(struct ixgb_adapter, m), \
+                               sizeof_field(struct ixgb_adapter, m), \
                                offsetof(struct ixgb_adapter, m)
 #define IXGB_NETDEV_STAT(m)    NETDEV_STATS, \
-                               FIELD_SIZEOF(struct net_device, m), \
+                               sizeof_field(struct net_device, m), \
                                offsetof(struct net_device, m)
 
 static struct ixgb_stats ixgb_gstrings_stats[] = {
index 54459b6..f7f309c 100644 (file)
@@ -31,14 +31,14 @@ struct ixgbe_stats {
 #define IXGBEVF_STAT(_name, _stat) { \
        .stat_string = _name, \
        .type = IXGBEVF_STATS, \
-       .sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, _stat), \
+       .sizeof_stat = sizeof_field(struct ixgbevf_adapter, _stat), \
        .stat_offset = offsetof(struct ixgbevf_adapter, _stat) \
 }
 
 #define IXGBEVF_NETDEV_STAT(_net_stat) { \
        .stat_string = #_net_stat, \
        .type = NETDEV_STATS, \
-       .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
+       .sizeof_stat = sizeof_field(struct net_device_stats, _net_stat), \
        .stat_offset = offsetof(struct net_device_stats, _net_stat) \
 }
 
index d5b6441..65a0932 100644 (file)
@@ -1432,11 +1432,11 @@ struct mv643xx_eth_stats {
 };
 
 #define SSTAT(m)                                               \
-       { #m, FIELD_SIZEOF(struct net_device_stats, m),         \
+       { #m, sizeof_field(struct net_device_stats, m),         \
          offsetof(struct net_device, stats.m), -1 }
 
 #define MIBSTAT(m)                                             \
-       { #m, FIELD_SIZEOF(struct mib_counters, m),             \
+       { #m, sizeof_field(struct mib_counters, m),             \
          -1, offsetof(struct mv643xx_eth_private, mib_counters.m) }
 
 static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
index a1202e5..8bf1f08 100644 (file)
@@ -611,7 +611,7 @@ static u32 ptys_get_active_port(struct mlx4_ptys_reg *ptys_reg)
 }
 
 #define MLX4_LINK_MODES_SZ \
-       (FIELD_SIZEOF(struct mlx4_ptys_reg, eth_proto_cap) * 8)
+       (sizeof_field(struct mlx4_ptys_reg, eth_proto_cap) * 8)
 
 enum ethtool_report {
        SUPPORTED = 0,
index f1a7bc4..2c16add 100644 (file)
@@ -816,7 +816,7 @@ struct mlx5e_xsk {
 struct mlx5e_priv {
        /* priv data path fields - start */
        struct mlx5e_txqsq *txq2sq[MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC];
-       int channel_tc2txq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
+       int channel_tc2realtxq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
 #ifdef CONFIG_MLX5_CORE_EN_DCB
        struct mlx5e_dcbx_dp       dcbx_dp;
 #endif
index f777994..fce6ecc 100644 (file)
@@ -73,6 +73,7 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = {
        [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000,
        [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR]   = 50000,
        [MLX5E_CAUI_4_100GBASE_CR4_KR4]         = 100000,
+       [MLX5E_100GAUI_2_100GBASE_CR2_KR2]      = 100000,
        [MLX5E_200GAUI_4_200GBASE_CR4_KR4]      = 200000,
        [MLX5E_400GAUI_8]                       = 400000,
 };
index 7b672ad..ae99fac 100644 (file)
@@ -155,8 +155,11 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
                }
 
                if (port_buffer->buffer[i].size <
-                   (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT)))
+                   (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) {
+                       pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n",
+                              i, port_buffer->buffer[i].size);
                        return -ENOMEM;
+               }
 
                port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff;
                port_buffer->buffer[i].xon  =
@@ -232,6 +235,26 @@ static int update_buffer_lossy(unsigned int max_mtu,
        return 0;
 }
 
+static int fill_pfc_en(struct mlx5_core_dev *mdev, u8 *pfc_en)
+{
+       u32 g_rx_pause, g_tx_pause;
+       int err;
+
+       err = mlx5_query_port_pause(mdev, &g_rx_pause, &g_tx_pause);
+       if (err)
+               return err;
+
+       /* If global pause enabled, set all active buffers to lossless.
+        * Otherwise, check PFC setting.
+        */
+       if (g_rx_pause || g_tx_pause)
+               *pfc_en = 0xff;
+       else
+               err = mlx5_query_port_pfc(mdev, pfc_en, NULL);
+
+       return err;
+}
+
 #define MINIMUM_MAX_MTU 9216
 int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
                                    u32 change, unsigned int mtu,
@@ -277,7 +300,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
 
        if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
                update_prio2buffer = true;
-               err = mlx5_query_port_pfc(priv->mdev, &curr_pfc_en, NULL);
+               err = fill_pfc_en(priv->mdev, &curr_pfc_en);
                if (err)
                        return err;
 
index 6ed8753..af4ebd2 100644 (file)
@@ -297,10 +297,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
 
        int ret;
 
-       ret = ipv6_stub->ipv6_dst_lookup(dev_net(mirred_dev), NULL, &dst,
-                                        fl6);
-       if (ret < 0)
-               return ret;
+       dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(mirred_dev), NULL, fl6,
+                                             NULL);
+       if (IS_ERR(dst))
+               return PTR_ERR(dst);
 
        if (!(*out_ttl))
                *out_ttl = ip6_dst_hoplimit(dst);
@@ -329,7 +329,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
        struct net_device *out_dev, *route_dev;
        struct flowi6 fl6 = {};
        struct ipv6hdr *ip6h;
-       struct neighbour *n;
+       struct neighbour *n = NULL;
        int ipv6_encap_size;
        char *encap_header;
        u8 nud_state, ttl;
index 9560126..c6776f3 100644 (file)
@@ -1027,18 +1027,11 @@ static bool ext_link_mode_requested(const unsigned long *adver)
        return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS);
 }
 
-static bool ext_speed_requested(u32 speed)
-{
-#define MLX5E_MAX_PTYS_LEGACY_SPEED 100000
-       return !!(speed > MLX5E_MAX_PTYS_LEGACY_SPEED);
-}
-
-static bool ext_requested(u8 autoneg, const unsigned long *adver, u32 speed)
+static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_supported)
 {
        bool ext_link_mode = ext_link_mode_requested(adver);
-       bool ext_speed = ext_speed_requested(speed);
 
-       return  autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_speed;
+       return  autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported;
 }
 
 int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
@@ -1065,8 +1058,8 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
        autoneg = link_ksettings->base.autoneg;
        speed = link_ksettings->base.speed;
 
-       ext = ext_requested(autoneg, adver, speed),
        ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
+       ext = ext_requested(autoneg, adver, ext_supported);
        if (!ext_supported && ext)
                return -EOPNOTSUPP;
 
@@ -1643,7 +1636,7 @@ static int mlx5e_get_module_info(struct net_device *netdev,
                break;
        case MLX5_MODULE_ID_SFP:
                modinfo->type       = ETH_MODULE_SFF_8472;
-               modinfo->eeprom_len = MLX5_EEPROM_PAGE_LENGTH;
+               modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
                break;
        default:
                netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
index 09ed7f5..4980e80 100644 (file)
@@ -1691,11 +1691,10 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c,
                          struct mlx5e_params *params,
                          struct mlx5e_channel_param *cparam)
 {
-       struct mlx5e_priv *priv = c->priv;
        int err, tc;
 
        for (tc = 0; tc < params->num_tc; tc++) {
-               int txq_ix = c->ix + tc * priv->max_nch;
+               int txq_ix = c->ix + tc * params->num_channels;
 
                err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix,
                                       params, &cparam->sq, &c->sq[tc], tc);
@@ -2876,26 +2875,21 @@ static void mlx5e_netdev_set_tcs(struct net_device *netdev)
                netdev_set_tc_queue(netdev, tc, nch, 0);
 }
 
-static void mlx5e_build_tc2txq_maps(struct mlx5e_priv *priv)
+static void mlx5e_build_txq_maps(struct mlx5e_priv *priv)
 {
-       int i, tc;
+       int i, ch;
 
-       for (i = 0; i < priv->max_nch; i++)
-               for (tc = 0; tc < priv->profile->max_tc; tc++)
-                       priv->channel_tc2txq[i][tc] = i + tc * priv->max_nch;
-}
+       ch = priv->channels.num;
 
-static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv)
-{
-       struct mlx5e_channel *c;
-       struct mlx5e_txqsq *sq;
-       int i, tc;
+       for (i = 0; i < ch; i++) {
+               int tc;
+
+               for (tc = 0; tc < priv->channels.params.num_tc; tc++) {
+                       struct mlx5e_channel *c = priv->channels.c[i];
+                       struct mlx5e_txqsq *sq = &c->sq[tc];
 
-       for (i = 0; i < priv->channels.num; i++) {
-               c = priv->channels.c[i];
-               for (tc = 0; tc < c->num_tc; tc++) {
-                       sq = &c->sq[tc];
                        priv->txq2sq[sq->txq_ix] = sq;
+                       priv->channel_tc2realtxq[i][tc] = i + tc * ch;
                }
        }
 }
@@ -2910,7 +2904,7 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv)
        netif_set_real_num_tx_queues(netdev, num_txqs);
        netif_set_real_num_rx_queues(netdev, num_rxqs);
 
-       mlx5e_build_tx2sq_maps(priv);
+       mlx5e_build_txq_maps(priv);
        mlx5e_activate_channels(&priv->channels);
        mlx5e_xdp_tx_enable(priv);
        netif_tx_start_all_queues(priv->netdev);
@@ -5021,7 +5015,6 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
        if (err)
                mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
        mlx5e_build_nic_netdev(netdev);
-       mlx5e_build_tc2txq_maps(priv);
        mlx5e_health_create_reporters(priv);
 
        return 0;
index 7e6ebd0..9f09253 100644 (file)
@@ -1601,7 +1601,7 @@ static int mlx5e_grp_channels_fill_strings(struct mlx5e_priv *priv, u8 *data,
                        for (j = 0; j < NUM_SQ_STATS; j++)
                                sprintf(data + (idx++) * ETH_GSTRING_LEN,
                                        sq_stats_desc[j].format,
-                                       priv->channel_tc2txq[i][tc]);
+                                       i + tc * max_nch);
 
        for (i = 0; i < max_nch; i++) {
                for (j = 0; j < NUM_XSKSQ_STATS * is_xsk; j++)
index 0d5d84b..9b32a9c 100644 (file)
@@ -1626,8 +1626,11 @@ static void __mlx5e_tc_del_fdb_peer_flow(struct mlx5e_tc_flow *flow)
 
        flow_flag_clear(flow, DUP);
 
-       mlx5e_tc_del_fdb_flow(flow->peer_flow->priv, flow->peer_flow);
-       kvfree(flow->peer_flow);
+       if (refcount_dec_and_test(&flow->peer_flow->refcnt)) {
+               mlx5e_tc_del_fdb_flow(flow->peer_flow->priv, flow->peer_flow);
+               kfree(flow->peer_flow);
+       }
+
        flow->peer_flow = NULL;
 }
 
index 66951ff..2565ba8 100644 (file)
@@ -93,7 +93,7 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
        if (txq_ix >= num_channels)
                txq_ix = priv->txq2sq[txq_ix]->ch_ix;
 
-       return priv->channel_tc2txq[txq_ix][up];
+       return priv->channel_tc2realtxq[txq_ix][up];
 }
 
 static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
index 962888a..ffcff3b 100644 (file)
@@ -81,7 +81,14 @@ struct vport_ingress {
                struct mlx5_fc *drop_counter;
        } legacy;
        struct {
-               struct mlx5_flow_group *metadata_grp;
+               /* Optional group to add an FTE to do internal priority
+                * tagging on ingress packets.
+                */
+               struct mlx5_flow_group *metadata_prio_tag_grp;
+               /* Group to add default match-all FTE entry to tag ingress
+                * packet with metadata.
+                */
+               struct mlx5_flow_group *metadata_allmatch_grp;
                struct mlx5_modify_hdr *modify_metadata;
                struct mlx5_flow_handle *modify_metadata_rule;
        } offloads;
index 8ba59a2..243a544 100644 (file)
@@ -88,6 +88,14 @@ u16 mlx5_eswitch_get_prio_range(struct mlx5_eswitch *esw)
        return 1;
 }
 
+static bool
+esw_check_ingress_prio_tag_enabled(const struct mlx5_eswitch *esw,
+                                  const struct mlx5_vport *vport)
+{
+       return (MLX5_CAP_GEN(esw->dev, prio_tag_required) &&
+               mlx5_eswitch_is_vf_vport(esw, vport->vport));
+}
+
 static void
 mlx5_eswitch_set_rule_source_port(struct mlx5_eswitch *esw,
                                  struct mlx5_flow_spec *spec,
@@ -1760,12 +1768,9 @@ static int esw_vport_ingress_prio_tag_config(struct mlx5_eswitch *esw,
         * required, allow
         * Unmatched traffic is allowed by default
         */
-
        spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
-       if (!spec) {
-               err = -ENOMEM;
-               goto out_no_mem;
-       }
+       if (!spec)
+               return -ENOMEM;
 
        /* Untagged packets - push prio tag VLAN, allow */
        MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.cvlan_tag);
@@ -1791,14 +1796,9 @@ static int esw_vport_ingress_prio_tag_config(struct mlx5_eswitch *esw,
                         "vport[%d] configure ingress untagged allow rule, err(%d)\n",
                         vport->vport, err);
                vport->ingress.allow_rule = NULL;
-               goto out;
        }
 
-out:
        kvfree(spec);
-out_no_mem:
-       if (err)
-               esw_vport_cleanup_ingress_rules(esw, vport);
        return err;
 }
 
@@ -1836,13 +1836,9 @@ static int esw_vport_add_ingress_acl_modify_metadata(struct mlx5_eswitch *esw,
                esw_warn(esw->dev,
                         "failed to add setting metadata rule for vport %d ingress acl, err(%d)\n",
                         vport->vport, err);
+               mlx5_modify_header_dealloc(esw->dev, vport->ingress.offloads.modify_metadata);
                vport->ingress.offloads.modify_metadata_rule = NULL;
-               goto out;
        }
-
-out:
-       if (err)
-               mlx5_modify_header_dealloc(esw->dev, vport->ingress.offloads.modify_metadata);
        return err;
 }
 
@@ -1862,50 +1858,103 @@ static int esw_vport_create_ingress_acl_group(struct mlx5_eswitch *esw,
 {
        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
        struct mlx5_flow_group *g;
+       void *match_criteria;
        u32 *flow_group_in;
+       u32 flow_index = 0;
        int ret = 0;
 
        flow_group_in = kvzalloc(inlen, GFP_KERNEL);
        if (!flow_group_in)
                return -ENOMEM;
 
-       memset(flow_group_in, 0, inlen);
-       MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0);
-       MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 0);
+       if (esw_check_ingress_prio_tag_enabled(esw, vport)) {
+               /* This group is to hold FTE to match untagged packets when prio_tag
+                * is enabled.
+                */
+               memset(flow_group_in, 0, inlen);
 
-       g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
-       if (IS_ERR(g)) {
-               ret = PTR_ERR(g);
-               esw_warn(esw->dev,
-                        "Failed to create vport[%d] ingress metadata group, err(%d)\n",
-                        vport->vport, ret);
-               goto grp_err;
+               match_criteria = MLX5_ADDR_OF(create_flow_group_in,
+                                             flow_group_in, match_criteria);
+               MLX5_SET(create_flow_group_in, flow_group_in,
+                        match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
+               MLX5_SET_TO_ONES(fte_match_param, match_criteria, outer_headers.cvlan_tag);
+               MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_index);
+               MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_index);
+
+               g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
+               if (IS_ERR(g)) {
+                       ret = PTR_ERR(g);
+                       esw_warn(esw->dev, "vport[%d] ingress create untagged flow group, err(%d)\n",
+                                vport->vport, ret);
+                       goto prio_tag_err;
+               }
+               vport->ingress.offloads.metadata_prio_tag_grp = g;
+               flow_index++;
+       }
+
+       if (mlx5_eswitch_vport_match_metadata_enabled(esw)) {
+               /* This group holds an FTE with no matches for add metadata for
+                * tagged packets, if prio-tag is enabled (as a fallthrough),
+                * or all traffic in case prio-tag is disabled.
+                */
+               memset(flow_group_in, 0, inlen);
+               MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_index);
+               MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_index);
+
+               g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
+               if (IS_ERR(g)) {
+                       ret = PTR_ERR(g);
+                       esw_warn(esw->dev, "vport[%d] ingress create drop flow group, err(%d)\n",
+                                vport->vport, ret);
+                       goto metadata_err;
+               }
+               vport->ingress.offloads.metadata_allmatch_grp = g;
+       }
+
+       kvfree(flow_group_in);
+       return 0;
+
+metadata_err:
+       if (!IS_ERR_OR_NULL(vport->ingress.offloads.metadata_prio_tag_grp)) {
+               mlx5_destroy_flow_group(vport->ingress.offloads.metadata_prio_tag_grp);
+               vport->ingress.offloads.metadata_prio_tag_grp = NULL;
        }
-       vport->ingress.offloads.metadata_grp = g;
-grp_err:
+prio_tag_err:
        kvfree(flow_group_in);
        return ret;
 }
 
 static void esw_vport_destroy_ingress_acl_group(struct mlx5_vport *vport)
 {
-       if (vport->ingress.offloads.metadata_grp) {
-               mlx5_destroy_flow_group(vport->ingress.offloads.metadata_grp);
-               vport->ingress.offloads.metadata_grp = NULL;
+       if (vport->ingress.offloads.metadata_allmatch_grp) {
+               mlx5_destroy_flow_group(vport->ingress.offloads.metadata_allmatch_grp);
+               vport->ingress.offloads.metadata_allmatch_grp = NULL;
+       }
+
+       if (vport->ingress.offloads.metadata_prio_tag_grp) {
+               mlx5_destroy_flow_group(vport->ingress.offloads.metadata_prio_tag_grp);
+               vport->ingress.offloads.metadata_prio_tag_grp = NULL;
        }
 }
 
 static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
                                    struct mlx5_vport *vport)
 {
+       int num_ftes = 0;
        int err;
 
        if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
-           !MLX5_CAP_GEN(esw->dev, prio_tag_required))
+           !esw_check_ingress_prio_tag_enabled(esw, vport))
                return 0;
 
        esw_vport_cleanup_ingress_rules(esw, vport);
-       err = esw_vport_create_ingress_acl_table(esw, vport, 1);
+
+       if (mlx5_eswitch_vport_match_metadata_enabled(esw))
+               num_ftes++;
+       if (esw_check_ingress_prio_tag_enabled(esw, vport))
+               num_ftes++;
+
+       err = esw_vport_create_ingress_acl_table(esw, vport, num_ftes);
        if (err) {
                esw_warn(esw->dev,
                         "failed to enable ingress acl (%d) on vport[%d]\n",
@@ -1926,8 +1975,7 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
                        goto metadata_err;
        }
 
-       if (MLX5_CAP_GEN(esw->dev, prio_tag_required) &&
-           mlx5_eswitch_is_vf_vport(esw, vport->vport)) {
+       if (esw_check_ingress_prio_tag_enabled(esw, vport)) {
                err = esw_vport_ingress_prio_tag_config(esw, vport);
                if (err)
                        goto prio_tag_err;
@@ -1937,7 +1985,6 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
 prio_tag_err:
        esw_vport_del_ingress_acl_modify_metadata(esw, vport);
 metadata_err:
-       esw_vport_cleanup_ingress_rules(esw, vport);
        esw_vport_destroy_ingress_acl_group(vport);
 group_err:
        esw_vport_destroy_ingress_acl_table(vport);
@@ -2008,8 +2055,9 @@ esw_vport_create_offloads_acl_tables(struct mlx5_eswitch *esw,
        if (mlx5_eswitch_is_vf_vport(esw, vport->vport)) {
                err = esw_vport_egress_config(esw, vport);
                if (err) {
-                       esw_vport_del_ingress_acl_modify_metadata(esw, vport);
                        esw_vport_cleanup_ingress_rules(esw, vport);
+                       esw_vport_del_ingress_acl_modify_metadata(esw, vport);
+                       esw_vport_destroy_ingress_acl_group(vport);
                        esw_vport_destroy_ingress_acl_table(vport);
                }
        }
@@ -2021,8 +2069,8 @@ esw_vport_destroy_offloads_acl_tables(struct mlx5_eswitch *esw,
                                      struct mlx5_vport *vport)
 {
        esw_vport_disable_egress_acl(esw, vport);
-       esw_vport_del_ingress_acl_modify_metadata(esw, vport);
        esw_vport_cleanup_ingress_rules(esw, vport);
+       esw_vport_del_ingress_acl_modify_metadata(esw, vport);
        esw_vport_destroy_ingress_acl_group(vport);
        esw_vport_destroy_ingress_acl_table(vport);
 }
index c76da30..e4ec0e0 100644 (file)
@@ -87,10 +87,10 @@ static const struct rhashtable_params rhash_sa = {
         * value is not constant during the lifetime
         * of the key object.
         */
-       .key_len = FIELD_SIZEOF(struct mlx5_fpga_ipsec_sa_ctx, hw_sa) -
-                  FIELD_SIZEOF(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd),
+       .key_len = sizeof_field(struct mlx5_fpga_ipsec_sa_ctx, hw_sa) -
+                  sizeof_field(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd),
        .key_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hw_sa) +
-                     FIELD_SIZEOF(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd),
+                     sizeof_field(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd),
        .head_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hash),
        .automatic_shrinking = true,
        .min_size = 1,
index d605774..9a48c43 100644 (file)
@@ -209,7 +209,7 @@ enum fs_i_lock_class {
 };
 
 static const struct rhashtable_params rhash_fte = {
-       .key_len = FIELD_SIZEOF(struct fs_fte, val),
+       .key_len = sizeof_field(struct fs_fte, val),
        .key_offset = offsetof(struct fs_fte, val),
        .head_offset = offsetof(struct fs_fte, hash),
        .automatic_shrinking = true,
@@ -217,7 +217,7 @@ static const struct rhashtable_params rhash_fte = {
 };
 
 static const struct rhashtable_params rhash_fg = {
-       .key_len = FIELD_SIZEOF(struct mlx5_flow_group, mask),
+       .key_len = sizeof_field(struct mlx5_flow_group, mask),
        .key_offset = offsetof(struct mlx5_flow_group, mask),
        .head_offset = offsetof(struct mlx5_flow_group, hash),
        .automatic_shrinking = true,
index 2cccadc..985b46d 100644 (file)
@@ -2149,14 +2149,18 @@ static struct ptp_clock_info ocelot_ptp_clock_info = {
 
 static int ocelot_init_timestamp(struct ocelot *ocelot)
 {
+       struct ptp_clock *ptp_clock;
+
        ocelot->ptp_info = ocelot_ptp_clock_info;
-       ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
-       if (IS_ERR(ocelot->ptp_clock))
-               return PTR_ERR(ocelot->ptp_clock);
+       ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
+       if (IS_ERR(ptp_clock))
+               return PTR_ERR(ptp_clock);
        /* Check if PHC support is missing at the configuration level */
-       if (!ocelot->ptp_clock)
+       if (!ptp_clock)
                return 0;
 
+       ocelot->ptp_clock = ptp_clock;
+
        ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
        ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
        ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
@@ -2489,6 +2493,8 @@ void ocelot_deinit(struct ocelot *ocelot)
        destroy_workqueue(ocelot->stats_queue);
        mutex_destroy(&ocelot->stats_lock);
        ocelot_ace_deinit();
+       if (ocelot->ptp_clock)
+               ptp_clock_unregister(ocelot->ptp_clock);
 
        for (i = 0; i < ocelot->num_phys_ports; i++) {
                port = ocelot->ports[i];
index c80bb83..0a721f6 100644 (file)
@@ -2652,17 +2652,17 @@ static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
 
        switch (meta->insn.off) {
        case offsetof(struct __sk_buff, len):
-               if (size != FIELD_SIZEOF(struct __sk_buff, len))
+               if (size != sizeof_field(struct __sk_buff, len))
                        return -EOPNOTSUPP;
                wrp_mov(nfp_prog, dst, plen_reg(nfp_prog));
                break;
        case offsetof(struct __sk_buff, data):
-               if (size != FIELD_SIZEOF(struct __sk_buff, data))
+               if (size != sizeof_field(struct __sk_buff, data))
                        return -EOPNOTSUPP;
                wrp_mov(nfp_prog, dst, pptr_reg(nfp_prog));
                break;
        case offsetof(struct __sk_buff, data_end):
-               if (size != FIELD_SIZEOF(struct __sk_buff, data_end))
+               if (size != sizeof_field(struct __sk_buff, data_end))
                        return -EOPNOTSUPP;
                emit_alu(nfp_prog, dst,
                         plen_reg(nfp_prog), ALU_OP_ADD, pptr_reg(nfp_prog));
@@ -2683,12 +2683,12 @@ static int mem_ldx_xdp(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
 
        switch (meta->insn.off) {
        case offsetof(struct xdp_md, data):
-               if (size != FIELD_SIZEOF(struct xdp_md, data))
+               if (size != sizeof_field(struct xdp_md, data))
                        return -EOPNOTSUPP;
                wrp_mov(nfp_prog, dst, pptr_reg(nfp_prog));
                break;
        case offsetof(struct xdp_md, data_end):
-               if (size != FIELD_SIZEOF(struct xdp_md, data_end))
+               if (size != sizeof_field(struct xdp_md, data_end))
                        return -EOPNOTSUPP;
                emit_alu(nfp_prog, dst,
                         plen_reg(nfp_prog), ALU_OP_ADD, pptr_reg(nfp_prog));
index 8f73277..11c83a9 100644 (file)
@@ -15,7 +15,7 @@
 
 const struct rhashtable_params nfp_bpf_maps_neutral_params = {
        .nelem_hint             = 4,
-       .key_len                = FIELD_SIZEOF(struct bpf_map, id),
+       .key_len                = sizeof_field(struct bpf_map, id),
        .key_offset             = offsetof(struct nfp_bpf_neutral_map, map_id),
        .head_offset            = offsetof(struct nfp_bpf_neutral_map, l),
        .automatic_shrinking    = true,
index 95a0d39..ac02369 100644 (file)
@@ -374,7 +374,7 @@ nfp_bpf_map_alloc(struct nfp_app_bpf *bpf, struct bpf_offloaded_map *offmap)
        }
 
        use_map_size = DIV_ROUND_UP(offmap->map.value_size, 4) *
-                      FIELD_SIZEOF(struct nfp_bpf_map, use_map[0]);
+                      sizeof_field(struct nfp_bpf_map, use_map[0]);
 
        nfp_map = kzalloc(sizeof(*nfp_map) + use_map_size, GFP_USER);
        if (!nfp_map)
index 31d9459..e0c985f 100644 (file)
@@ -24,7 +24,7 @@ struct nfp_app;
 #define NFP_FL_STAT_ID_MU_NUM          GENMASK(31, 22)
 #define NFP_FL_STAT_ID_STAT            GENMASK(21, 0)
 
-#define NFP_FL_STATS_ELEM_RS           FIELD_SIZEOF(struct nfp_fl_stats_id, \
+#define NFP_FL_STATS_ELEM_RS           sizeof_field(struct nfp_fl_stats_id, \
                                                     init_unalloc)
 #define NFP_FLOWER_MASK_ENTRY_RS       256
 #define NFP_FLOWER_MASK_ELEMENT_RS     1
index ebb81d6..6561692 100644 (file)
@@ -817,8 +817,6 @@ static int lpc_mii_init(struct netdata_local *pldat)
        pldat->mii_bus->priv = pldat;
        pldat->mii_bus->parent = &pldat->pdev->dev;
 
-       platform_set_drvdata(pldat->pdev, pldat->mii_bus);
-
        node = of_get_child_by_name(pldat->pdev->dev.of_node, "mdio");
        err = of_mdiobus_register(pldat->mii_bus, node);
        of_node_put(node);
index 1a3008e..b36aa5b 100644 (file)
@@ -20,7 +20,7 @@ struct pch_gbe_stats {
 #define PCH_GBE_STAT(m)                                                \
 {                                                              \
        .string = #m,                                           \
-       .size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m),       \
+       .size = sizeof_field(struct pch_gbe_hw_stats, m),       \
        .offset = offsetof(struct pch_gbe_hw_stats, m),         \
 }
 
index 60fd14d..ef82587 100644 (file)
@@ -1381,12 +1381,9 @@ int ionic_lif_rss_config(struct ionic_lif *lif, const u16 types,
 
 static int ionic_lif_rss_init(struct ionic_lif *lif)
 {
-       u8 rss_key[IONIC_RSS_HASH_KEY_SIZE];
        unsigned int tbl_sz;
        unsigned int i;
 
-       netdev_rss_key_fill(rss_key, IONIC_RSS_HASH_KEY_SIZE);
-
        lif->rss_types = IONIC_RSS_TYPE_IPV4     |
                         IONIC_RSS_TYPE_IPV4_TCP |
                         IONIC_RSS_TYPE_IPV4_UDP |
@@ -1399,12 +1396,18 @@ static int ionic_lif_rss_init(struct ionic_lif *lif)
        for (i = 0; i < tbl_sz; i++)
                lif->rss_ind_tbl[i] = ethtool_rxfh_indir_default(i, lif->nxqs);
 
-       return ionic_lif_rss_config(lif, lif->rss_types, rss_key, NULL);
+       return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL);
 }
 
-static int ionic_lif_rss_deinit(struct ionic_lif *lif)
+static void ionic_lif_rss_deinit(struct ionic_lif *lif)
 {
-       return ionic_lif_rss_config(lif, 0x0, NULL, NULL);
+       int tbl_sz;
+
+       tbl_sz = le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz);
+       memset(lif->rss_ind_tbl, 0, tbl_sz);
+       memset(lif->rss_hash_key, 0, IONIC_RSS_HASH_KEY_SIZE);
+
+       ionic_lif_rss_config(lif, 0x0, NULL, NULL);
 }
 
 static void ionic_txrx_disable(struct ionic_lif *lif)
@@ -1729,6 +1732,7 @@ static struct ionic_lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index
                dev_err(dev, "Failed to allocate rss indirection table, aborting\n");
                goto err_out_free_qcqs;
        }
+       netdev_rss_key_fill(lif->rss_hash_key, IONIC_RSS_HASH_KEY_SIZE);
 
        list_add_tail(&lif->list, &ionic->lifs);
 
index c303a92..e8a1b27 100644 (file)
@@ -464,7 +464,7 @@ struct qede_fastpath {
        struct qede_tx_queue    *txq;
        struct qede_tx_queue    *xdp_tx;
 
-#define VEC_NAME_SIZE  (FIELD_SIZEOF(struct net_device, name) + 8)
+#define VEC_NAME_SIZE  (sizeof_field(struct net_device, name) + 8)
        char    name[VEC_NAME_SIZE];
 };
 
index a4cd6f2..75d83c3 100644 (file)
@@ -20,7 +20,7 @@ struct qlcnic_stats {
        int stat_offset;
 };
 
-#define QLC_SIZEOF(m) FIELD_SIZEOF(struct qlcnic_adapter, m)
+#define QLC_SIZEOF(m) sizeof_field(struct qlcnic_adapter, m)
 #define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
 static const u32 qlcnic_fw_dump_level[] = {
        0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
index 355cc81..cbc6b84 100644 (file)
@@ -37,7 +37,7 @@ struct fw_info {
        u8      chksum;
 } __packed;
 
-#define FW_OPCODE_SIZE FIELD_SIZEOF(struct rtl_fw_phy_action, code[0])
+#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
 
 static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
 {
index 38d2126..67a4d5d 100644 (file)
@@ -3695,7 +3695,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_32:
        case RTL_GIGA_MAC_VER_33:
        case RTL_GIGA_MAC_VER_34:
-       case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_52:
+       case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_61:
                RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
                        AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
                break;
@@ -3896,7 +3896,7 @@ static void rtl_hw_jumbo_disable(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28:
                r8168dp_hw_jumbo_disable(tp);
                break;
-       case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_34:
+       case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33:
                r8168e_hw_jumbo_disable(tp);
                break;
        default:
index 0775b94..466483c 100644 (file)
@@ -30,7 +30,7 @@ struct sxgbe_stats {
 #define SXGBE_STAT(m)                                          \
 {                                                              \
        #m,                                                     \
-       FIELD_SIZEOF(struct sxgbe_extra_stats, m),              \
+       sizeof_field(struct sxgbe_extra_stats, m),              \
        offsetof(struct sxgbe_priv_data, xstats.m)              \
 }
 
index 1a76883..b29603e 100644 (file)
@@ -34,7 +34,7 @@ struct stmmac_stats {
 };
 
 #define STMMAC_STAT(m) \
-       { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m),       \
+       { #m, sizeof_field(struct stmmac_extra_stats, m),       \
        offsetof(struct stmmac_priv, xstats.m)}
 
 static const struct stmmac_stats stmmac_gstrings_stats[] = {
@@ -163,7 +163,7 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
 
 /* HW MAC Management counters (if supported) */
 #define STMMAC_MMC_STAT(m)     \
-       { #m, FIELD_SIZEOF(struct stmmac_counters, m),  \
+       { #m, sizeof_field(struct stmmac_counters, m),  \
        offsetof(struct stmmac_priv, mmc.m)}
 
 static const struct stmmac_stats stmmac_mmc[] = {
index 644cb5d..bbc65bd 100644 (file)
@@ -2009,6 +2009,8 @@ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan)
        tx_q->cur_tx = 0;
        tx_q->mss = 0;
        netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, chan));
+       stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
+                           tx_q->dma_tx_phy, chan);
        stmmac_start_tx_dma(priv, chan);
 
        priv->dev->stats.tx_errors++;
index 9170572..a46f418 100644 (file)
@@ -62,7 +62,7 @@ config TI_CPSW
 config TI_CPSW_SWITCHDEV
        tristate "TI CPSW Switch Support with switchdev"
        depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || COMPILE_TEST
-       select NET_SWITCHDEV
+       depends on NET_SWITCHDEV
        select TI_DAVINCI_MDIO
        select MFD_SYSCON
        select REGMAP
index 31248a6..fa54efe 100644 (file)
@@ -73,13 +73,13 @@ enum {
 };
 
 #define CPSW_STAT(m)           CPSW_STATS,                             \
-                               FIELD_SIZEOF(struct cpsw_hw_stats, m), \
+                               sizeof_field(struct cpsw_hw_stats, m), \
                                offsetof(struct cpsw_hw_stats, m)
 #define CPDMA_RX_STAT(m)       CPDMA_RX_STATS,                            \
-                               FIELD_SIZEOF(struct cpdma_chan_stats, m), \
+                               sizeof_field(struct cpdma_chan_stats, m), \
                                offsetof(struct cpdma_chan_stats, m)
 #define CPDMA_TX_STAT(m)       CPDMA_TX_STATS,                            \
-                               FIELD_SIZEOF(struct cpdma_chan_stats, m), \
+                               sizeof_field(struct cpdma_chan_stats, m), \
                                offsetof(struct cpdma_chan_stats, m)
 
 static const struct cpsw_stats cpsw_gstrings_stats[] = {
index b833cc1..707d5eb 100644 (file)
@@ -100,8 +100,8 @@ irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id)
 {
        struct cpsw_common *cpsw = dev_id;
 
-       cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX);
        writel(0, &cpsw->wr_regs->rx_en);
+       cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX);
 
        if (cpsw->quirk_irq) {
                disable_irq_nosync(cpsw->irqs_table[0]);
index 86a3f42..d6a192c 100644 (file)
@@ -783,28 +783,28 @@ struct netcp_ethtool_stat {
 #define GBE_STATSA_INFO(field)                                         \
 {                                                                      \
        "GBE_A:"#field, GBE_STATSA_MODULE,                              \
-       FIELD_SIZEOF(struct gbe_hw_stats, field),                       \
+       sizeof_field(struct gbe_hw_stats, field),                       \
        offsetof(struct gbe_hw_stats, field)                            \
 }
 
 #define GBE_STATSB_INFO(field)                                         \
 {                                                                      \
        "GBE_B:"#field, GBE_STATSB_MODULE,                              \
-       FIELD_SIZEOF(struct gbe_hw_stats, field),                       \
+       sizeof_field(struct gbe_hw_stats, field),                       \
        offsetof(struct gbe_hw_stats, field)                            \
 }
 
 #define GBE_STATSC_INFO(field)                                         \
 {                                                                      \
        "GBE_C:"#field, GBE_STATSC_MODULE,                              \
-       FIELD_SIZEOF(struct gbe_hw_stats, field),                       \
+       sizeof_field(struct gbe_hw_stats, field),                       \
        offsetof(struct gbe_hw_stats, field)                            \
 }
 
 #define GBE_STATSD_INFO(field)                                         \
 {                                                                      \
        "GBE_D:"#field, GBE_STATSD_MODULE,                              \
-       FIELD_SIZEOF(struct gbe_hw_stats, field),                       \
+       sizeof_field(struct gbe_hw_stats, field),                       \
        offsetof(struct gbe_hw_stats, field)                            \
 }
 
@@ -957,7 +957,7 @@ static const struct netcp_ethtool_stat gbe13_et_stats[] = {
 #define GBENU_STATS_HOST(field)                                        \
 {                                                              \
        "GBE_HOST:"#field, GBENU_STATS0_MODULE,                 \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
@@ -967,56 +967,56 @@ static const struct netcp_ethtool_stat gbe13_et_stats[] = {
 #define GBENU_STATS_P1(field)                                  \
 {                                                              \
        "GBE_P1:"#field, GBENU_STATS1_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
 #define GBENU_STATS_P2(field)                                  \
 {                                                              \
        "GBE_P2:"#field, GBENU_STATS2_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
 #define GBENU_STATS_P3(field)                                  \
 {                                                              \
        "GBE_P3:"#field, GBENU_STATS3_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
 #define GBENU_STATS_P4(field)                                  \
 {                                                              \
        "GBE_P4:"#field, GBENU_STATS4_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
 #define GBENU_STATS_P5(field)                                  \
 {                                                              \
        "GBE_P5:"#field, GBENU_STATS5_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
 #define GBENU_STATS_P6(field)                                  \
 {                                                              \
        "GBE_P6:"#field, GBENU_STATS6_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
 #define GBENU_STATS_P7(field)                                  \
 {                                                              \
        "GBE_P7:"#field, GBENU_STATS7_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
 #define GBENU_STATS_P8(field)                                  \
 {                                                              \
        "GBE_P8:"#field, GBENU_STATS8_MODULE,                   \
-       FIELD_SIZEOF(struct gbenu_hw_stats, field),             \
+       sizeof_field(struct gbenu_hw_stats, field),             \
        offsetof(struct gbenu_hw_stats, field)                  \
 }
 
@@ -1607,21 +1607,21 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] = {
 #define XGBE_STATS0_INFO(field)                                \
 {                                                      \
        "GBE_0:"#field, XGBE_STATS0_MODULE,             \
-       FIELD_SIZEOF(struct xgbe_hw_stats, field),      \
+       sizeof_field(struct xgbe_hw_stats, field),      \
        offsetof(struct xgbe_hw_stats, field)           \
 }
 
 #define XGBE_STATS1_INFO(field)                                \
 {                                                      \
        "GBE_1:"#field, XGBE_STATS1_MODULE,             \
-       FIELD_SIZEOF(struct xgbe_hw_stats, field),      \
+       sizeof_field(struct xgbe_hw_stats, field),      \
        offsetof(struct xgbe_hw_stats, field)           \
 }
 
 #define XGBE_STATS2_INFO(field)                                \
 {                                                      \
        "GBE_2:"#field, XGBE_STATS2_MODULE,             \
-       FIELD_SIZEOF(struct xgbe_hw_stats, field),      \
+       sizeof_field(struct xgbe_hw_stats, field),      \
        offsetof(struct xgbe_hw_stats, field)           \
 }
 
index 09f3604..746736c 100644 (file)
@@ -21,7 +21,7 @@ struct fjes_stats {
 
 #define FJES_STAT(name, stat) { \
        .stat_string = name, \
-       .sizeof_stat = FIELD_SIZEOF(struct fjes_adapter, stat), \
+       .sizeof_stat = sizeof_field(struct fjes_adapter, stat), \
        .stat_offset = offsetof(struct fjes_adapter, stat) \
 }
 
index 3ab24fd..75757e9 100644 (file)
@@ -853,7 +853,9 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
                if (dst)
                        return dst;
        }
-       if (ipv6_stub->ipv6_dst_lookup(geneve->net, gs6->sock->sk, &dst, fl6)) {
+       dst = ipv6_stub->ipv6_dst_lookup_flow(geneve->net, gs6->sock->sk, fl6,
+                                             NULL);
+       if (IS_ERR(dst)) {
                netdev_dbg(dev, "no route to %pI6\n", &fl6->daddr);
                return ERR_PTR(-ENETUNREACH);
        }
@@ -1154,7 +1156,7 @@ static void geneve_setup(struct net_device *dev)
 
 static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
        [IFLA_GENEVE_ID]                = { .type = NLA_U32 },
-       [IFLA_GENEVE_REMOTE]            = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
+       [IFLA_GENEVE_REMOTE]            = { .len = sizeof_field(struct iphdr, daddr) },
        [IFLA_GENEVE_REMOTE6]           = { .len = sizeof(struct in6_addr) },
        [IFLA_GENEVE_TTL]               = { .type = NLA_U8 },
        [IFLA_GENEVE_TOS]               = { .type = NLA_U8 },
index eff8fef..02e6647 100644 (file)
@@ -571,7 +571,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
 
        /* Use the skb control buffer for building up the packet */
        BUILD_BUG_ON(sizeof(struct hv_netvsc_packet) >
-                       FIELD_SIZEOF(struct sk_buff, cb));
+                       sizeof_field(struct sk_buff, cb));
        packet = (struct hv_netvsc_packet *)skb->cb;
 
        packet->q_idx = skb_get_queue_mapping(skb);
index 0b95e7a..9cd9dce 100644 (file)
 /* RGMIIDCTL bits */
 #define DP83867_RGMII_TX_CLK_DELAY_MAX         0xf
 #define DP83867_RGMII_TX_CLK_DELAY_SHIFT       4
+#define DP83867_RGMII_TX_CLK_DELAY_INV (DP83867_RGMII_TX_CLK_DELAY_MAX + 1)
 #define DP83867_RGMII_RX_CLK_DELAY_MAX         0xf
 #define DP83867_RGMII_RX_CLK_DELAY_SHIFT       0
+#define DP83867_RGMII_RX_CLK_DELAY_INV (DP83867_RGMII_RX_CLK_DELAY_MAX + 1)
+
 
 /* IO_MUX_CFG bits */
 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MASK   0x1f
@@ -294,6 +297,48 @@ static int dp83867_config_port_mirroring(struct phy_device *phydev)
        return 0;
 }
 
+static int dp83867_verify_rgmii_cfg(struct phy_device *phydev)
+{
+       struct dp83867_private *dp83867 = phydev->priv;
+
+       /* Existing behavior was to use default pin strapping delay in rgmii
+        * mode, but rgmii should have meant no delay.  Warn existing users.
+        */
+       if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
+               const u16 val = phy_read_mmd(phydev, DP83867_DEVADDR,
+                                            DP83867_STRAP_STS2);
+               const u16 txskew = (val & DP83867_STRAP_STS2_CLK_SKEW_TX_MASK) >>
+                                  DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT;
+               const u16 rxskew = (val & DP83867_STRAP_STS2_CLK_SKEW_RX_MASK) >>
+                                  DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT;
+
+               if (txskew != DP83867_STRAP_STS2_CLK_SKEW_NONE ||
+                   rxskew != DP83867_STRAP_STS2_CLK_SKEW_NONE)
+                       phydev_warn(phydev,
+                                   "PHY has delays via pin strapping, but phy-mode = 'rgmii'\n"
+                                   "Should be 'rgmii-id' to use internal delays txskew:%x rxskew:%x\n",
+                                   txskew, rxskew);
+       }
+
+       /* RX delay *must* be specified if internal delay of RX is used. */
+       if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+            phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) &&
+            dp83867->rx_id_delay == DP83867_RGMII_RX_CLK_DELAY_INV) {
+               phydev_err(phydev, "ti,rx-internal-delay must be specified\n");
+               return -EINVAL;
+       }
+
+       /* TX delay *must* be specified if internal delay of TX is used. */
+       if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+            phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) &&
+            dp83867->tx_id_delay == DP83867_RGMII_TX_CLK_DELAY_INV) {
+               phydev_err(phydev, "ti,tx-internal-delay must be specified\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 #ifdef CONFIG_OF_MDIO
 static int dp83867_of_init(struct phy_device *phydev)
 {
@@ -335,55 +380,25 @@ static int dp83867_of_init(struct phy_device *phydev)
        dp83867->sgmii_ref_clk_en = of_property_read_bool(of_node,
                                        "ti,sgmii-ref-clock-output-enable");
 
-       /* Existing behavior was to use default pin strapping delay in rgmii
-        * mode, but rgmii should have meant no delay.  Warn existing users.
-        */
-       if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
-               const u16 val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS2);
-               const u16 txskew = (val & DP83867_STRAP_STS2_CLK_SKEW_TX_MASK) >>
-                                  DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT;
-               const u16 rxskew = (val & DP83867_STRAP_STS2_CLK_SKEW_RX_MASK) >>
-                                  DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT;
 
-               if (txskew != DP83867_STRAP_STS2_CLK_SKEW_NONE ||
-                   rxskew != DP83867_STRAP_STS2_CLK_SKEW_NONE)
-                       phydev_warn(phydev,
-                                   "PHY has delays via pin strapping, but phy-mode = 'rgmii'\n"
-                                   "Should be 'rgmii-id' to use internal delays\n");
-       }
-
-       /* RX delay *must* be specified if internal delay of RX is used. */
-       if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
-           phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
-               ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
-                                          &dp83867->rx_id_delay);
-               if (ret) {
-                       phydev_err(phydev, "ti,rx-internal-delay must be specified\n");
-                       return ret;
-               }
-               if (dp83867->rx_id_delay > DP83867_RGMII_RX_CLK_DELAY_MAX) {
-                       phydev_err(phydev,
-                                  "ti,rx-internal-delay value of %u out of range\n",
-                                  dp83867->rx_id_delay);
-                       return -EINVAL;
-               }
+       dp83867->rx_id_delay = DP83867_RGMII_RX_CLK_DELAY_INV;
+       ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
+                                  &dp83867->rx_id_delay);
+       if (!ret && dp83867->rx_id_delay > DP83867_RGMII_RX_CLK_DELAY_MAX) {
+               phydev_err(phydev,
+                          "ti,rx-internal-delay value of %u out of range\n",
+                          dp83867->rx_id_delay);
+               return -EINVAL;
        }
 
-       /* TX delay *must* be specified if internal delay of RX is used. */
-       if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
-           phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
-               ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
-                                          &dp83867->tx_id_delay);
-               if (ret) {
-                       phydev_err(phydev, "ti,tx-internal-delay must be specified\n");
-                       return ret;
-               }
-               if (dp83867->tx_id_delay > DP83867_RGMII_TX_CLK_DELAY_MAX) {
-                       phydev_err(phydev,
-                                  "ti,tx-internal-delay value of %u out of range\n",
-                                  dp83867->tx_id_delay);
-                       return -EINVAL;
-               }
+       dp83867->tx_id_delay = DP83867_RGMII_TX_CLK_DELAY_INV;
+       ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
+                                  &dp83867->tx_id_delay);
+       if (!ret && dp83867->tx_id_delay > DP83867_RGMII_TX_CLK_DELAY_MAX) {
+               phydev_err(phydev,
+                          "ti,tx-internal-delay value of %u out of range\n",
+                          dp83867->tx_id_delay);
+               return -EINVAL;
        }
 
        if (of_property_read_bool(of_node, "enet-phy-lane-swap"))
@@ -434,6 +449,10 @@ static int dp83867_config_init(struct phy_device *phydev)
        int ret, val, bs;
        u16 delay;
 
+       ret = dp83867_verify_rgmii_cfg(phydev);
+       if (ret)
+               return ret;
+
        /* RX_DV/RX_CTRL strapped in mode 1 or mode 2 workaround */
        if (dp83867->rxctrl_strap_quirk)
                phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
@@ -485,8 +504,12 @@ static int dp83867_config_init(struct phy_device *phydev)
 
                phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, val);
 
-               delay = (dp83867->rx_id_delay |
-                       (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
+               delay = 0;
+               if (dp83867->rx_id_delay != DP83867_RGMII_RX_CLK_DELAY_INV)
+                       delay |= dp83867->rx_id_delay;
+               if (dp83867->tx_id_delay != DP83867_RGMII_TX_CLK_DELAY_INV)
+                       delay |= dp83867->tx_id_delay <<
+                                DP83867_RGMII_TX_CLK_DELAY_SHIFT;
 
                phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL,
                              delay);
index b6128ae..2a97938 100644 (file)
@@ -129,6 +129,7 @@ static void thunder_mdiobus_pci_remove(struct pci_dev *pdev)
                mdiobus_free(bus->mii_bus);
                oct_mdio_writeq(0, bus->register_base + SMI_EN);
        }
+       pci_release_regions(pdev);
        pci_set_drvdata(pdev, NULL);
 }
 
index bdbbb76..c0b9a8e 100644 (file)
@@ -1754,6 +1754,10 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
                        break;
                }
 
+               err = sfp_hwmon_insert(sfp);
+               if (err)
+                       dev_warn(sfp->dev, "hwmon probe failed: %d\n", err);
+
                sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0);
                /* fall through */
        case SFP_MOD_WAITDEV:
@@ -1803,15 +1807,6 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
        case SFP_MOD_ERROR:
                break;
        }
-
-#if IS_ENABLED(CONFIG_HWMON)
-       if (sfp->sm_mod_state >= SFP_MOD_WAITDEV &&
-           IS_ERR_OR_NULL(sfp->hwmon_dev)) {
-               err = sfp_hwmon_insert(sfp);
-               if (err)
-                       dev_warn(sfp->dev, "hwmon probe failed: %d\n", err);
-       }
-#endif
 }
 
 static void sfp_sm_main(struct sfp *sfp, unsigned int event)
@@ -2294,6 +2289,10 @@ static int sfp_remove(struct platform_device *pdev)
 
        sfp_unregister_socket(sfp->sfp_bus);
 
+       rtnl_lock();
+       sfp_sm_event(sfp, SFP_E_REMOVE);
+       rtnl_unlock();
+
        return 0;
 }
 
index 0cb1c2d..3bf8a8b 100644 (file)
@@ -564,8 +564,9 @@ static struct bpf_prog *get_filter(struct sock_fprog *uprog)
                return NULL;
 
        /* uprog->len is unsigned short, so no overflow here */
-       fprog.len = uprog->len * sizeof(struct sock_filter);
-       fprog.filter = memdup_user(uprog->filter, fprog.len);
+       fprog.len = uprog->len;
+       fprog.filter = memdup_user(uprog->filter,
+                                  uprog->len * sizeof(struct sock_filter));
        if (IS_ERR(fprog.filter))
                return ERR_CAST(fprog.filter);
 
index a44dd3c..d760a36 100644 (file)
@@ -119,8 +119,6 @@ static inline bool stage_session(__be16 sid)
 
 static inline struct pppoe_net *pppoe_pernet(struct net *net)
 {
-       BUG_ON(!net);
-
        return net_generic(net, pppoe_net_id);
 }
 
index 34c1eab..389d19d 100644 (file)
@@ -865,7 +865,7 @@ static struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev,
        u16 len;
        bool need_tail;
 
-       BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
+       BUILD_BUG_ON(sizeof_field(struct usbnet, data)
                                < sizeof(struct cdc_state));
 
        dev_dbg(&dev->udev->dev, "%s", __func__);
index 30e511c..9ce6d30 100644 (file)
@@ -2184,7 +2184,7 @@ static int __init usbnet_init(void)
 {
        /* Compiler should optimize this out. */
        BUILD_BUG_ON(
-               FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data));
+               sizeof_field(struct sk_buff, cb) < sizeof(struct skb_data));
 
        eth_random_addr(node_id);
        return 0;
index bf04bc2..3ec6b50 100644 (file)
@@ -2275,7 +2275,6 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
        bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
        struct dst_entry *ndst;
        struct flowi6 fl6;
-       int err;
 
        if (!sock6)
                return ERR_PTR(-EIO);
@@ -2298,10 +2297,9 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
        fl6.fl6_dport = dport;
        fl6.fl6_sport = sport;
 
-       err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
-                                        sock6->sock->sk,
-                                        &ndst, &fl6);
-       if (unlikely(err < 0)) {
+       ndst = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk,
+                                              &fl6, NULL);
+       if (unlikely(IS_ERR(ndst))) {
                netdev_dbg(dev, "no route to %pI6\n", daddr);
                return ERR_PTR(-ENETUNREACH);
        }
@@ -3071,10 +3069,10 @@ static void vxlan_raw_setup(struct net_device *dev)
 
 static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
        [IFLA_VXLAN_ID]         = { .type = NLA_U32 },
-       [IFLA_VXLAN_GROUP]      = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
+       [IFLA_VXLAN_GROUP]      = { .len = sizeof_field(struct iphdr, daddr) },
        [IFLA_VXLAN_GROUP6]     = { .len = sizeof(struct in6_addr) },
        [IFLA_VXLAN_LINK]       = { .type = NLA_U32 },
-       [IFLA_VXLAN_LOCAL]      = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
+       [IFLA_VXLAN_LOCAL]      = { .len = sizeof_field(struct iphdr, saddr) },
        [IFLA_VXLAN_LOCAL6]     = { .len = sizeof(struct in6_addr) },
        [IFLA_VXLAN_TOS]        = { .type = NLA_U8 },
        [IFLA_VXLAN_TTL]        = { .type = NLA_U8 },
index fe14814..c604613 100644 (file)
@@ -774,7 +774,7 @@ void lbs_debugfs_remove_one(struct lbs_private *priv)
 
 #ifdef PROC_DEBUG
 
-#define item_size(n)   (FIELD_SIZEOF(struct lbs_private, n))
+#define item_size(n)   (sizeof_field(struct lbs_private, n))
 #define item_addr(n)   (offsetof(struct lbs_private, n))
 
 
index c386992..7cafcec 100644 (file)
@@ -36,11 +36,11 @@ struct mwifiex_cb {
 };
 
 /* size/addr for mwifiex_debug_info */
-#define item_size(n)           (FIELD_SIZEOF(struct mwifiex_debug_info, n))
+#define item_size(n)           (sizeof_field(struct mwifiex_debug_info, n))
 #define item_addr(n)           (offsetof(struct mwifiex_debug_info, n))
 
 /* size/addr for struct mwifiex_adapter */
-#define adapter_item_size(n)   (FIELD_SIZEOF(struct mwifiex_adapter, n))
+#define adapter_item_size(n)   (sizeof_field(struct mwifiex_adapter, n))
 #define adapter_item_addr(n)   (offsetof(struct mwifiex_adapter, n))
 
 struct mwifiex_debug_data {
index 156c2a1..e52b300 100644 (file)
@@ -1139,6 +1139,7 @@ static const struct ntb_dev_data dev_data[] = {
 static const struct pci_device_id amd_ntb_pci_tbl[] = {
        { PCI_VDEVICE(AMD, 0x145b), (kernel_ulong_t)&dev_data[0] },
        { PCI_VDEVICE(AMD, 0x148b), (kernel_ulong_t)&dev_data[1] },
+       { PCI_VDEVICE(HYGON, 0x145b), (kernel_ulong_t)&dev_data[0] },
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, amd_ntb_pci_tbl);
index dfe37a5..667f18f 100644 (file)
@@ -1735,6 +1735,8 @@ static int nvme_report_ns_ids(struct nvme_ctrl *ctrl, unsigned int nsid,
                if (ret)
                        dev_warn(ctrl->device,
                                 "Identify Descriptors failed (%d)\n", ret);
+               if (ret > 0)
+                       ret = 0;
        }
        return ret;
 }
@@ -2852,6 +2854,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
                 * admin connect
                 */
                if (ctrl->cntlid != le16_to_cpu(id->cntlid)) {
+                       dev_err(ctrl->device,
+                               "Mismatching cntlid: Connect %u vs Identify "
+                               "%u, rejecting\n",
+                               ctrl->cntlid, le16_to_cpu(id->cntlid));
                        ret = -EINVAL;
                        goto out_free;
                }
index 679a721..5a70ac3 100644 (file)
@@ -95,7 +95,7 @@ struct nvme_fc_fcp_op {
 
 struct nvme_fcp_op_w_sgl {
        struct nvme_fc_fcp_op   op;
-       struct scatterlist      sgl[SG_CHUNK_SIZE];
+       struct scatterlist      sgl[NVME_INLINE_SG_CNT];
        uint8_t                 priv[0];
 };
 
@@ -342,7 +342,8 @@ nvme_fc_register_localport(struct nvme_fc_port_info *pinfo,
            !template->ls_req || !template->fcp_io ||
            !template->ls_abort || !template->fcp_abort ||
            !template->max_hw_queues || !template->max_sgl_segments ||
-           !template->max_dif_sgl_segments || !template->dma_boundary) {
+           !template->max_dif_sgl_segments || !template->dma_boundary ||
+           !template->module) {
                ret = -EINVAL;
                goto out_reghost_failed;
        }
@@ -2015,6 +2016,7 @@ nvme_fc_ctrl_free(struct kref *ref)
 {
        struct nvme_fc_ctrl *ctrl =
                container_of(ref, struct nvme_fc_ctrl, ref);
+       struct nvme_fc_lport *lport = ctrl->lport;
        unsigned long flags;
 
        if (ctrl->ctrl.tagset) {
@@ -2041,6 +2043,7 @@ nvme_fc_ctrl_free(struct kref *ref)
        if (ctrl->ctrl.opts)
                nvmf_free_options(ctrl->ctrl.opts);
        kfree(ctrl);
+       module_put(lport->ops->module);
 }
 
 static void
@@ -2141,7 +2144,7 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
        freq->sg_table.sgl = freq->first_sgl;
        ret = sg_alloc_table_chained(&freq->sg_table,
                        blk_rq_nr_phys_segments(rq), freq->sg_table.sgl,
-                       SG_CHUNK_SIZE);
+                       NVME_INLINE_SG_CNT);
        if (ret)
                return -ENOMEM;
 
@@ -2150,7 +2153,7 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
        freq->sg_cnt = fc_dma_map_sg(ctrl->lport->dev, freq->sg_table.sgl,
                                op->nents, rq_dma_dir(rq));
        if (unlikely(freq->sg_cnt <= 0)) {
-               sg_free_table_chained(&freq->sg_table, SG_CHUNK_SIZE);
+               sg_free_table_chained(&freq->sg_table, NVME_INLINE_SG_CNT);
                freq->sg_cnt = 0;
                return -EFAULT;
        }
@@ -2173,7 +2176,7 @@ nvme_fc_unmap_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
        fc_dma_unmap_sg(ctrl->lport->dev, freq->sg_table.sgl, op->nents,
                        rq_dma_dir(rq));
 
-       sg_free_table_chained(&freq->sg_table, SG_CHUNK_SIZE);
+       sg_free_table_chained(&freq->sg_table, NVME_INLINE_SG_CNT);
 
        freq->sg_cnt = 0;
 }
@@ -2910,10 +2913,22 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
 static void
 __nvme_fc_terminate_io(struct nvme_fc_ctrl *ctrl)
 {
-       nvme_stop_keep_alive(&ctrl->ctrl);
+       /*
+        * if state is connecting - the error occurred as part of a
+        * reconnect attempt. The create_association error paths will
+        * clean up any outstanding io.
+        *
+        * if it's a different state - ensure all pending io is
+        * terminated. Given this can delay while waiting for the
+        * aborted io to return, we recheck adapter state below
+        * before changing state.
+        */
+       if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) {
+               nvme_stop_keep_alive(&ctrl->ctrl);
 
-       /* will block will waiting for io to terminate */
-       nvme_fc_delete_association(ctrl);
+               /* will block will waiting for io to terminate */
+               nvme_fc_delete_association(ctrl);
+       }
 
        if (ctrl->ctrl.state != NVME_CTRL_CONNECTING &&
            !nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING))
@@ -3059,10 +3074,15 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
                goto out_fail;
        }
 
+       if (!try_module_get(lport->ops->module)) {
+               ret = -EUNATCH;
+               goto out_free_ctrl;
+       }
+
        idx = ida_simple_get(&nvme_fc_ctrl_cnt, 0, 0, GFP_KERNEL);
        if (idx < 0) {
                ret = -ENOSPC;
-               goto out_free_ctrl;
+               goto out_mod_put;
        }
 
        ctrl->ctrl.opts = opts;
@@ -3215,6 +3235,8 @@ out_free_queues:
 out_free_ida:
        put_device(ctrl->dev);
        ida_simple_remove(&nvme_fc_ctrl_cnt, ctrl->cnum);
+out_mod_put:
+       module_put(lport->ops->module);
 out_free_ctrl:
        kfree(ctrl);
 out_fail:
index 3b9cbe0..1024fec 100644 (file)
@@ -28,6 +28,12 @@ extern unsigned int admin_timeout;
 #define NVME_DEFAULT_KATO      5
 #define NVME_KATO_GRACE                10
 
+#ifdef CONFIG_ARCH_NO_SG_CHAIN
+#define  NVME_INLINE_SG_CNT  0
+#else
+#define  NVME_INLINE_SG_CNT  2
+#endif
+
 extern struct workqueue_struct *nvme_wq;
 extern struct workqueue_struct *nvme_reset_wq;
 extern struct workqueue_struct *nvme_delete_wq;
index dcaad58..365a2dd 100644 (file)
@@ -68,14 +68,14 @@ static int io_queue_depth = 1024;
 module_param_cb(io_queue_depth, &io_queue_depth_ops, &io_queue_depth, 0644);
 MODULE_PARM_DESC(io_queue_depth, "set io queue depth, should >= 2");
 
-static int write_queues;
-module_param(write_queues, int, 0644);
+static unsigned int write_queues;
+module_param(write_queues, uint, 0644);
 MODULE_PARM_DESC(write_queues,
        "Number of queues to use for writes. If not set, reads and writes "
        "will share a queue set.");
 
-static int poll_queues;
-module_param(poll_queues, int, 0644);
+static unsigned int poll_queues;
+module_param(poll_queues, uint, 0644);
 MODULE_PARM_DESC(poll_queues, "Number of queues to use for polled IO.");
 
 struct nvme_dev;
@@ -176,7 +176,6 @@ struct nvme_queue {
        u16 sq_tail;
        u16 last_sq_tail;
        u16 cq_head;
-       u16 last_cq_head;
        u16 qid;
        u8 cq_phase;
        u8 sqes;
@@ -1026,10 +1025,7 @@ static irqreturn_t nvme_irq(int irq, void *data)
         * the irq handler, even if that was on another CPU.
         */
        rmb();
-       if (nvmeq->cq_head != nvmeq->last_cq_head)
-               ret = IRQ_HANDLED;
        nvme_process_cq(nvmeq, &start, &end, -1);
-       nvmeq->last_cq_head = nvmeq->cq_head;
        wmb();
 
        if (start != end) {
@@ -1549,7 +1545,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid, bool polled)
        result = adapter_alloc_sq(dev, qid, nvmeq);
        if (result < 0)
                return result;
-       else if (result)
+       if (result)
                goto release_cq;
 
        nvmeq->cq_vector = vector;
@@ -2058,7 +2054,6 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
                .priv           = dev,
        };
        unsigned int irq_queues, this_p_queues;
-       unsigned int nr_cpus = num_possible_cpus();
 
        /*
         * Poll queues don't need interrupts, but we need at least one IO
@@ -2069,10 +2064,7 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
                this_p_queues = nr_io_queues - 1;
                irq_queues = 1;
        } else {
-               if (nr_cpus < nr_io_queues - this_p_queues)
-                       irq_queues = nr_cpus + 1;
-               else
-                       irq_queues = nr_io_queues - this_p_queues + 1;
+               irq_queues = nr_io_queues - this_p_queues + 1;
        }
        dev->io_queues[HCTX_TYPE_POLL] = this_p_queues;
 
@@ -3142,6 +3134,9 @@ static int __init nvme_init(void)
        BUILD_BUG_ON(sizeof(struct nvme_create_sq) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64);
        BUILD_BUG_ON(IRQ_AFFINITY_MAX_SETS < 2);
+
+       write_queues = min(write_queues, num_possible_cpus());
+       poll_queues = min(poll_queues, num_possible_cpus());
        return pci_register_driver(&nvme_driver);
 }
 
index dce5945..2a47c6c 100644 (file)
@@ -731,7 +731,7 @@ static struct blk_mq_tag_set *nvme_rdma_alloc_tagset(struct nvme_ctrl *nctrl,
                set->reserved_tags = 2; /* connect + keep-alive */
                set->numa_node = nctrl->numa_node;
                set->cmd_size = sizeof(struct nvme_rdma_request) +
-                       SG_CHUNK_SIZE * sizeof(struct scatterlist);
+                       NVME_INLINE_SG_CNT * sizeof(struct scatterlist);
                set->driver_data = ctrl;
                set->nr_hw_queues = 1;
                set->timeout = ADMIN_TIMEOUT;
@@ -745,7 +745,7 @@ static struct blk_mq_tag_set *nvme_rdma_alloc_tagset(struct nvme_ctrl *nctrl,
                set->numa_node = nctrl->numa_node;
                set->flags = BLK_MQ_F_SHOULD_MERGE;
                set->cmd_size = sizeof(struct nvme_rdma_request) +
-                       SG_CHUNK_SIZE * sizeof(struct scatterlist);
+                       NVME_INLINE_SG_CNT * sizeof(struct scatterlist);
                set->driver_data = ctrl;
                set->nr_hw_queues = nctrl->queue_count - 1;
                set->timeout = NVME_IO_TIMEOUT;
@@ -1160,7 +1160,7 @@ static void nvme_rdma_unmap_data(struct nvme_rdma_queue *queue,
        }
 
        ib_dma_unmap_sg(ibdev, req->sg_table.sgl, req->nents, rq_dma_dir(rq));
-       sg_free_table_chained(&req->sg_table, SG_CHUNK_SIZE);
+       sg_free_table_chained(&req->sg_table, NVME_INLINE_SG_CNT);
 }
 
 static int nvme_rdma_set_sg_null(struct nvme_command *c)
@@ -1276,7 +1276,7 @@ static int nvme_rdma_map_data(struct nvme_rdma_queue *queue,
        req->sg_table.sgl = req->first_sgl;
        ret = sg_alloc_table_chained(&req->sg_table,
                        blk_rq_nr_phys_segments(rq), req->sg_table.sgl,
-                       SG_CHUNK_SIZE);
+                       NVME_INLINE_SG_CNT);
        if (ret)
                return -ENOMEM;
 
@@ -1314,7 +1314,7 @@ out:
 out_unmap_sg:
        ib_dma_unmap_sg(ibdev, req->sg_table.sgl, req->nents, rq_dma_dir(rq));
 out_free_table:
-       sg_free_table_chained(&req->sg_table, SG_CHUNK_SIZE);
+       sg_free_table_chained(&req->sg_table, NVME_INLINE_SG_CNT);
        return ret;
 }
 
index b50b53d..1c50af6 100644 (file)
@@ -850,6 +850,7 @@ fcloop_targetport_delete(struct nvmet_fc_target_port *targetport)
 #define FCLOOP_DMABOUND_4G             0xFFFFFFFF
 
 static struct nvme_fc_port_template fctemplate = {
+       .module                 = THIS_MODULE,
        .localport_delete       = fcloop_localport_delete,
        .remoteport_delete      = fcloop_remoteport_delete,
        .create_queue           = fcloop_create_queue,
index a758bb3..4df4ebd 100644 (file)
@@ -76,7 +76,7 @@ static void nvme_loop_complete_rq(struct request *req)
 {
        struct nvme_loop_iod *iod = blk_mq_rq_to_pdu(req);
 
-       sg_free_table_chained(&iod->sg_table, SG_CHUNK_SIZE);
+       sg_free_table_chained(&iod->sg_table, NVME_INLINE_SG_CNT);
        nvme_complete_rq(req);
 }
 
@@ -156,7 +156,7 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx,
                iod->sg_table.sgl = iod->first_sgl;
                if (sg_alloc_table_chained(&iod->sg_table,
                                blk_rq_nr_phys_segments(req),
-                               iod->sg_table.sgl, SG_CHUNK_SIZE)) {
+                               iod->sg_table.sgl, NVME_INLINE_SG_CNT)) {
                        nvme_cleanup_cmd(req);
                        return BLK_STS_RESOURCE;
                }
@@ -342,7 +342,7 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
        ctrl->admin_tag_set.reserved_tags = 2; /* connect + keep-alive */
        ctrl->admin_tag_set.numa_node = NUMA_NO_NODE;
        ctrl->admin_tag_set.cmd_size = sizeof(struct nvme_loop_iod) +
-               SG_CHUNK_SIZE * sizeof(struct scatterlist);
+               NVME_INLINE_SG_CNT * sizeof(struct scatterlist);
        ctrl->admin_tag_set.driver_data = ctrl;
        ctrl->admin_tag_set.nr_hw_queues = 1;
        ctrl->admin_tag_set.timeout = ADMIN_TIMEOUT;
@@ -516,7 +516,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
        ctrl->tag_set.numa_node = NUMA_NO_NODE;
        ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
        ctrl->tag_set.cmd_size = sizeof(struct nvme_loop_iod) +
-               SG_CHUNK_SIZE * sizeof(struct scatterlist);
+               NVME_INLINE_SG_CNT * sizeof(struct scatterlist);
        ctrl->tag_set.driver_data = ctrl;
        ctrl->tag_set.nr_hw_queues = ctrl->ctrl.queue_count - 1;
        ctrl->tag_set.timeout = NVME_IO_TIMEOUT;
index 39bd763..d6b5334 100644 (file)
 static int meson_efuse_read(void *context, unsigned int offset,
                            void *val, size_t bytes)
 {
-       return meson_sm_call_read((u8 *)val, bytes, SM_EFUSE_READ, offset,
+       struct meson_sm_firmware *fw = context;
+
+       return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
                                  bytes, 0, 0, 0);
 }
 
 static int meson_efuse_write(void *context, unsigned int offset,
                             void *val, size_t bytes)
 {
-       return meson_sm_call_write((u8 *)val, bytes, SM_EFUSE_WRITE, offset,
+       struct meson_sm_firmware *fw = context;
+
+       return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
                                   bytes, 0, 0, 0);
 }
 
@@ -37,12 +41,25 @@ MODULE_DEVICE_TABLE(of, meson_efuse_match);
 static int meson_efuse_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
+       struct meson_sm_firmware *fw;
+       struct device_node *sm_np;
        struct nvmem_device *nvmem;
        struct nvmem_config *econfig;
        struct clk *clk;
        unsigned int size;
        int ret;
 
+       sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+       if (!sm_np) {
+               dev_err(&pdev->dev, "no secure-monitor node\n");
+               return -ENODEV;
+       }
+
+       fw = meson_sm_get(sm_np);
+       of_node_put(sm_np);
+       if (!fw)
+               return -EPROBE_DEFER;
+
        clk = devm_clk_get(dev, NULL);
        if (IS_ERR(clk)) {
                ret = PTR_ERR(clk);
@@ -65,7 +82,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
                return ret;
        }
 
-       if (meson_sm_call(SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
+       if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
                dev_err(dev, "failed to get max user");
                return -EINVAL;
        }
@@ -81,6 +98,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
        econfig->reg_read = meson_efuse_read;
        econfig->reg_write = meson_efuse_write;
        econfig->size = size;
+       econfig->priv = fw;
 
        nvmem = devm_nvmem_register(&pdev->dev, econfig);
 
index d93891a..3371e4a 100644 (file)
@@ -518,10 +518,11 @@ static int __init of_platform_default_populate_init(void)
 {
        struct device_node *node;
 
+       device_links_supplier_sync_state_pause();
+
        if (!of_have_populated_dt())
                return -ENODEV;
 
-       device_links_supplier_sync_state_pause();
        /*
         * Handle certain compatibles explicitly, since we don't want to create
         * platform_devices for every node in /reserved-memory with a
@@ -545,8 +546,7 @@ arch_initcall_sync(of_platform_default_populate_init);
 
 static int __init of_platform_sync_state_init(void)
 {
-       if (of_have_populated_dt())
-               device_links_supplier_sync_state_resume();
+       device_links_supplier_sync_state_resume();
        return 0;
 }
 late_initcall_sync(of_platform_sync_state_init);
index d9b63bf..94af6f5 100644 (file)
@@ -834,10 +834,12 @@ static int rockchip_pcie_cfg_atu(struct rockchip_pcie *rockchip)
        if (!entry)
                return -ENODEV;
 
+       /* store the register number offset to program RC io outbound ATU */
+       offset = size >> 20;
+
        size = resource_size(entry->res);
        pci_addr = entry->res->start - entry->offset;
 
-       offset = size >> 20;
        for (reg_no = 0; reg_no < (size >> 20); reg_no++) {
                err = rockchip_pcie_prog_ob_atu(rockchip,
                                                reg_no + 1 + offset,
index 4053ba6..005e02d 100644 (file)
@@ -103,3 +103,14 @@ config PHY_PXA_USB
          The PHY driver will be used by Marvell udc/ehci/otg driver.
 
          To compile this driver as a module, choose M here.
+
+config PHY_MMP3_USB
+       tristate "Marvell MMP3 USB PHY Driver"
+       depends on MACH_MMP3_DT || COMPILE_TEST
+       select GENERIC_PHY
+       help
+         Enable this to support Marvell MMP3 USB PHY driver for Marvell
+         SoC. This driver will do the PHY initialization and shutdown.
+         The PHY driver will be used by Marvell udc/ehci/otg driver.
+
+         To compile this driver as a module, choose M here.
index 434eb9c..5a106b1 100644 (file)
@@ -2,6 +2,7 @@
 obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
 obj-$(CONFIG_PHY_BERLIN_SATA)          += phy-berlin-sata.o
 obj-$(CONFIG_PHY_BERLIN_USB)           += phy-berlin-usb.o
+obj-$(CONFIG_PHY_MMP3_USB)             += phy-mmp3-usb.o
 obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY)   += phy-mvebu-a3700-comphy.o
 obj-$(CONFIG_PHY_MVEBU_A3700_UTMI)     += phy-mvebu-a3700-utmi.o
 obj-$(CONFIG_PHY_MVEBU_A38X_COMPHY)    += phy-armada38x-comphy.o
diff --git a/drivers/phy/marvell/phy-mmp3-usb.c b/drivers/phy/marvell/phy-mmp3-usb.c
new file mode 100644 (file)
index 0000000..4998695
--- /dev/null
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ * Copyright (C) 2018,2019 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mmp/cputype.h>
+
+#define USB2_PLL_REG0          0x4
+#define USB2_PLL_REG1          0x8
+#define USB2_TX_REG0           0x10
+#define USB2_TX_REG1           0x14
+#define USB2_TX_REG2           0x18
+#define USB2_RX_REG0           0x20
+#define USB2_RX_REG1           0x24
+#define USB2_RX_REG2           0x28
+#define USB2_ANA_REG0          0x30
+#define USB2_ANA_REG1          0x34
+#define USB2_ANA_REG2          0x38
+#define USB2_DIG_REG0          0x3C
+#define USB2_DIG_REG1          0x40
+#define USB2_DIG_REG2          0x44
+#define USB2_DIG_REG3          0x48
+#define USB2_TEST_REG0         0x4C
+#define USB2_TEST_REG1         0x50
+#define USB2_TEST_REG2         0x54
+#define USB2_CHARGER_REG0      0x58
+#define USB2_OTG_REG0          0x5C
+#define USB2_PHY_MON0          0x60
+#define USB2_RESETVE_REG0      0x64
+#define USB2_ICID_REG0         0x78
+#define USB2_ICID_REG1         0x7C
+
+/* USB2_PLL_REG0 */
+
+/* This is for Ax stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3              0
+#define USB2_PLL_FBDIV_MASK_MMP3               (0xFF << 0)
+
+#define USB2_PLL_REFDIV_SHIFT_MMP3             8
+#define USB2_PLL_REFDIV_MASK_MMP3              (0xF << 8)
+
+#define USB2_PLL_VDD12_SHIFT_MMP3              12
+#define USB2_PLL_VDD18_SHIFT_MMP3              14
+
+/* This is for B0 stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3_B0           0
+#define USB2_PLL_REFDIV_SHIFT_MMP3_B0          9
+#define USB2_PLL_VDD18_SHIFT_MMP3_B0           14
+#define USB2_PLL_FBDIV_MASK_MMP3_B0            0x01FF
+#define USB2_PLL_REFDIV_MASK_MMP3_B0           0x3E00
+
+#define USB2_PLL_CAL12_SHIFT_MMP3              0
+#define USB2_PLL_CALI12_MASK_MMP3              (0x3 << 0)
+
+#define USB2_PLL_VCOCAL_START_SHIFT_MMP3       2
+
+#define USB2_PLL_KVCO_SHIFT_MMP3               4
+#define USB2_PLL_KVCO_MASK_MMP3                        (0x7<<4)
+
+#define USB2_PLL_ICP_SHIFT_MMP3                        8
+#define USB2_PLL_ICP_MASK_MMP3                 (0x7<<8)
+
+#define USB2_PLL_LOCK_BYPASS_SHIFT_MMP3                12
+
+#define USB2_PLL_PU_PLL_SHIFT_MMP3             13
+#define USB2_PLL_PU_PLL_MASK                   (0x1 << 13)
+
+#define USB2_PLL_READY_MASK_MMP3               (0x1 << 15)
+
+/* USB2_TX_REG0 */
+#define USB2_TX_IMPCAL_VTH_SHIFT_MMP3          8
+#define USB2_TX_IMPCAL_VTH_MASK_MMP3           (0x7 << 8)
+
+#define USB2_TX_RCAL_START_SHIFT_MMP3          13
+
+/* USB2_TX_REG1 */
+#define USB2_TX_CK60_PHSEL_SHIFT_MMP3          0
+#define USB2_TX_CK60_PHSEL_MASK_MMP3           (0xf << 0)
+
+#define USB2_TX_AMP_SHIFT_MMP3                 4
+#define USB2_TX_AMP_MASK_MMP3                  (0x7 << 4)
+
+#define USB2_TX_VDD12_SHIFT_MMP3               8
+#define USB2_TX_VDD12_MASK_MMP3                        (0x3 << 8)
+
+/* USB2_TX_REG2 */
+#define USB2_TX_DRV_SLEWRATE_SHIFT             10
+
+/* USB2_RX_REG0 */
+#define USB2_RX_SQ_THRESH_SHIFT_MMP3           4
+#define USB2_RX_SQ_THRESH_MASK_MMP3            (0xf << 4)
+
+#define USB2_RX_SQ_LENGTH_SHIFT_MMP3           10
+#define USB2_RX_SQ_LENGTH_MASK_MMP3            (0x3 << 10)
+
+/* USB2_ANA_REG1*/
+#define USB2_ANA_PU_ANA_SHIFT_MMP3             14
+
+/* USB2_OTG_REG0 */
+#define USB2_OTG_PU_OTG_SHIFT_MMP3             3
+
+struct mmp3_usb_phy {
+       struct phy *phy;
+       void __iomem *base;
+};
+
+static unsigned int u2o_get(void __iomem *base, unsigned int offset)
+{
+       return readl_relaxed(base + offset);
+}
+
+static void u2o_set(void __iomem *base, unsigned int offset,
+               unsigned int value)
+{
+       u32 reg;
+
+       reg = readl_relaxed(base + offset);
+       reg |= value;
+       writel_relaxed(reg, base + offset);
+       readl_relaxed(base + offset);
+}
+
+static void u2o_clear(void __iomem *base, unsigned int offset,
+               unsigned int value)
+{
+       u32 reg;
+
+       reg = readl_relaxed(base + offset);
+       reg &= ~value;
+       writel_relaxed(reg, base + offset);
+       readl_relaxed(base + offset);
+}
+
+static int mmp3_usb_phy_init(struct phy *phy)
+{
+       struct mmp3_usb_phy *mmp3_usb_phy = phy_get_drvdata(phy);
+       void __iomem *base = mmp3_usb_phy->base;
+
+       if (cpu_is_mmp3_a0()) {
+               u2o_clear(base, USB2_PLL_REG0, (USB2_PLL_FBDIV_MASK_MMP3
+                       | USB2_PLL_REFDIV_MASK_MMP3));
+               u2o_set(base, USB2_PLL_REG0,
+                       0xd << USB2_PLL_REFDIV_SHIFT_MMP3
+                       | 0xf0 << USB2_PLL_FBDIV_SHIFT_MMP3);
+       } else if (cpu_is_mmp3_b0()) {
+               u2o_clear(base, USB2_PLL_REG0, USB2_PLL_REFDIV_MASK_MMP3_B0
+                       | USB2_PLL_FBDIV_MASK_MMP3_B0);
+               u2o_set(base, USB2_PLL_REG0,
+                       0xd << USB2_PLL_REFDIV_SHIFT_MMP3_B0
+                       | 0xf0 << USB2_PLL_FBDIV_SHIFT_MMP3_B0);
+       } else {
+               dev_err(&phy->dev, "unsupported silicon revision\n");
+               return -ENODEV;
+       }
+
+       u2o_clear(base, USB2_PLL_REG1, USB2_PLL_PU_PLL_MASK
+               | USB2_PLL_ICP_MASK_MMP3
+               | USB2_PLL_KVCO_MASK_MMP3
+               | USB2_PLL_CALI12_MASK_MMP3);
+       u2o_set(base, USB2_PLL_REG1, 1 << USB2_PLL_PU_PLL_SHIFT_MMP3
+               | 1 << USB2_PLL_LOCK_BYPASS_SHIFT_MMP3
+               | 3 << USB2_PLL_ICP_SHIFT_MMP3
+               | 3 << USB2_PLL_KVCO_SHIFT_MMP3
+               | 3 << USB2_PLL_CAL12_SHIFT_MMP3);
+
+       u2o_clear(base, USB2_TX_REG0, USB2_TX_IMPCAL_VTH_MASK_MMP3);
+       u2o_set(base, USB2_TX_REG0, 2 << USB2_TX_IMPCAL_VTH_SHIFT_MMP3);
+
+       u2o_clear(base, USB2_TX_REG1, USB2_TX_VDD12_MASK_MMP3
+               | USB2_TX_AMP_MASK_MMP3
+               | USB2_TX_CK60_PHSEL_MASK_MMP3);
+       u2o_set(base, USB2_TX_REG1, 3 << USB2_TX_VDD12_SHIFT_MMP3
+               | 4 << USB2_TX_AMP_SHIFT_MMP3
+               | 4 << USB2_TX_CK60_PHSEL_SHIFT_MMP3);
+
+       u2o_clear(base, USB2_TX_REG2, 3 << USB2_TX_DRV_SLEWRATE_SHIFT);
+       u2o_set(base, USB2_TX_REG2, 2 << USB2_TX_DRV_SLEWRATE_SHIFT);
+
+       u2o_clear(base, USB2_RX_REG0, USB2_RX_SQ_THRESH_MASK_MMP3);
+       u2o_set(base, USB2_RX_REG0, 0xa << USB2_RX_SQ_THRESH_SHIFT_MMP3);
+
+       u2o_set(base, USB2_ANA_REG1, 0x1 << USB2_ANA_PU_ANA_SHIFT_MMP3);
+
+       u2o_set(base, USB2_OTG_REG0, 0x1 << USB2_OTG_PU_OTG_SHIFT_MMP3);
+
+       return 0;
+}
+
+static int mmp3_usb_phy_calibrate(struct phy *phy)
+{
+       struct mmp3_usb_phy *mmp3_usb_phy = phy_get_drvdata(phy);
+       void __iomem *base = mmp3_usb_phy->base;
+       int loops;
+
+       /*
+        * PLL VCO and TX Impedance Calibration Timing:
+        *
+        *                _____________________________________
+        * PU  __________|
+        *                        _____________________________
+        * VCOCAL START _________|
+        *                                 ___
+        * REG_RCAL_START ________________|   |________|_______
+        *               | 200us | 400us  | 40| 400us  | USB PHY READY
+        */
+
+       udelay(200);
+       u2o_set(base, USB2_PLL_REG1, 1 << USB2_PLL_VCOCAL_START_SHIFT_MMP3);
+       udelay(400);
+       u2o_set(base, USB2_TX_REG0, 1 << USB2_TX_RCAL_START_SHIFT_MMP3);
+       udelay(40);
+       u2o_clear(base, USB2_TX_REG0, 1 << USB2_TX_RCAL_START_SHIFT_MMP3);
+       udelay(400);
+
+       loops = 0;
+       while ((u2o_get(base, USB2_PLL_REG1) & USB2_PLL_READY_MASK_MMP3) == 0) {
+               mdelay(1);
+               loops++;
+               if (loops > 100) {
+                       dev_err(&phy->dev, "PLL_READY not set after 100mS.\n");
+                       return -ETIMEDOUT;
+               }
+       }
+
+       return 0;
+}
+
+static const struct phy_ops mmp3_usb_phy_ops = {
+       .init           = mmp3_usb_phy_init,
+       .calibrate      = mmp3_usb_phy_calibrate,
+       .owner          = THIS_MODULE,
+};
+
+static const struct of_device_id mmp3_usb_phy_of_match[] = {
+       { .compatible = "marvell,mmp3-usb-phy", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, mmp3_usb_phy_of_match);
+
+static int mmp3_usb_phy_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct resource *resource;
+       struct mmp3_usb_phy *mmp3_usb_phy;
+       struct phy_provider *provider;
+
+       mmp3_usb_phy = devm_kzalloc(dev, sizeof(*mmp3_usb_phy), GFP_KERNEL);
+       if (!mmp3_usb_phy)
+               return -ENOMEM;
+
+       resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mmp3_usb_phy->base = devm_ioremap_resource(dev, resource);
+       if (IS_ERR(mmp3_usb_phy->base)) {
+               dev_err(dev, "failed to remap PHY regs\n");
+               return PTR_ERR(mmp3_usb_phy->base);
+       }
+
+       mmp3_usb_phy->phy = devm_phy_create(dev, NULL, &mmp3_usb_phy_ops);
+       if (IS_ERR(mmp3_usb_phy->phy)) {
+               dev_err(dev, "failed to create PHY\n");
+               return PTR_ERR(mmp3_usb_phy->phy);
+       }
+
+       phy_set_drvdata(mmp3_usb_phy->phy, mmp3_usb_phy);
+       provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+       if (IS_ERR(provider)) {
+               dev_err(dev, "failed to register PHY provider\n");
+               return PTR_ERR(provider);
+       }
+
+       return 0;
+}
+
+static struct platform_driver mmp3_usb_phy_driver = {
+       .probe          = mmp3_usb_phy_probe,
+       .driver         = {
+               .name   = "mmp3-usb-phy",
+               .of_match_table = mmp3_usb_phy_of_match,
+       },
+};
+module_platform_driver(mmp3_usb_phy_driver);
+
+MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
+MODULE_DESCRIPTION("Marvell MMP3 USB PHY Driver");
+MODULE_LICENSE("GPL v2");
index b5a217b..089b624 100644 (file)
@@ -13,9 +13,9 @@ menuconfig POWER_AVS
          Say Y here to enable Adaptive Voltage Scaling class support.
 
 config ROCKCHIP_IODOMAIN
-        tristate "Rockchip IO domain support"
-        depends on POWER_AVS && ARCH_ROCKCHIP && OF
-        help
-          Say y here to enable support io domains on Rockchip SoCs. It is
-          necessary for the io domain setting of the SoC to match the
-          voltage supplied by the regulators.
+       tristate "Rockchip IO domain support"
+       depends on POWER_AVS && ARCH_ROCKCHIP && OF
+       help
+         Say y here to enable support io domains on Rockchip SoCs. It is
+         necessary for the io domain setting of the SoC to match the
+         voltage supplied by the regulators.
index 359b085..7ff48c1 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/mfd/stm32-timers.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 
 #define CCMR_CHANNEL_MASK  0xFF
 #define MAX_BREAKINPUT 2
 
+struct stm32_breakinput {
+       u32 index;
+       u32 level;
+       u32 filter;
+};
+
 struct stm32_pwm {
        struct pwm_chip chip;
        struct mutex lock; /* protect pwm config/enable */
@@ -26,15 +33,11 @@ struct stm32_pwm {
        struct regmap *regmap;
        u32 max_arr;
        bool have_complementary_output;
+       struct stm32_breakinput breakinputs[MAX_BREAKINPUT];
+       unsigned int num_breakinputs;
        u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */
 };
 
-struct stm32_breakinput {
-       u32 index;
-       u32 level;
-       u32 filter;
-};
-
 static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip)
 {
        return container_of(chip, struct stm32_pwm, chip);
@@ -488,22 +491,19 @@ static const struct pwm_ops stm32pwm_ops = {
 };
 
 static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
-                                   int index, int level, int filter)
+                                   const struct stm32_breakinput *bi)
 {
-       u32 bke = (index == 0) ? TIM_BDTR_BKE : TIM_BDTR_BK2E;
-       int shift = (index == 0) ? TIM_BDTR_BKF_SHIFT : TIM_BDTR_BK2F_SHIFT;
-       u32 mask = (index == 0) ? TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF
-                               : TIM_BDTR_BK2E | TIM_BDTR_BK2P | TIM_BDTR_BK2F;
-       u32 bdtr = bke;
+       u32 shift = TIM_BDTR_BKF_SHIFT(bi->index);
+       u32 bke = TIM_BDTR_BKE(bi->index);
+       u32 bkp = TIM_BDTR_BKP(bi->index);
+       u32 bkf = TIM_BDTR_BKF(bi->index);
+       u32 mask = bkf | bkp | bke;
+       u32 bdtr;
 
-       /*
-        * The both bits could be set since only one will be wrote
-        * due to mask value.
-        */
-       if (level)
-               bdtr |= TIM_BDTR_BKP | TIM_BDTR_BK2P;
+       bdtr = (bi->filter & TIM_BDTR_BKF_MASK) << shift | bke;
 
-       bdtr |= (filter & TIM_BDTR_BKF_MASK) << shift;
+       if (bi->level)
+               bdtr |= bkp;
 
        regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr);
 
@@ -512,11 +512,25 @@ static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
        return (bdtr & bke) ? 0 : -EINVAL;
 }
 
-static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv,
+static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv)
+{
+       unsigned int i;
+       int ret;
+
+       for (i = 0; i < priv->num_breakinputs; i++) {
+               ret = stm32_pwm_set_breakinput(priv, &priv->breakinputs[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int stm32_pwm_probe_breakinputs(struct stm32_pwm *priv,
                                       struct device_node *np)
 {
-       struct stm32_breakinput breakinput[MAX_BREAKINPUT];
-       int nb, ret, i, array_size;
+       int nb, ret, array_size;
+       unsigned int i;
 
        nb = of_property_count_elems_of_size(np, "st,breakinput",
                                             sizeof(struct stm32_breakinput));
@@ -531,20 +545,21 @@ static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv,
        if (nb > MAX_BREAKINPUT)
                return -EINVAL;
 
+       priv->num_breakinputs = nb;
        array_size = nb * sizeof(struct stm32_breakinput) / sizeof(u32);
        ret = of_property_read_u32_array(np, "st,breakinput",
-                                        (u32 *)breakinput, array_size);
+                                        (u32 *)priv->breakinputs, array_size);
        if (ret)
                return ret;
 
-       for (i = 0; i < nb && !ret; i++) {
-               ret = stm32_pwm_set_breakinput(priv,
-                                              breakinput[i].index,
-                                              breakinput[i].level,
-                                              breakinput[i].filter);
+       for (i = 0; i < priv->num_breakinputs; i++) {
+               if (priv->breakinputs[i].index > 1 ||
+                   priv->breakinputs[i].level > 1 ||
+                   priv->breakinputs[i].filter > 15)
+                       return -EINVAL;
        }
 
-       return ret;
+       return stm32_pwm_apply_breakinputs(priv);
 }
 
 static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
@@ -614,7 +629,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
        if (!priv->regmap || !priv->clk)
                return -EINVAL;
 
-       ret = stm32_pwm_apply_breakinputs(priv, np);
+       ret = stm32_pwm_probe_breakinputs(priv, np);
        if (ret)
                return ret;
 
@@ -647,6 +662,42 @@ static int stm32_pwm_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused stm32_pwm_suspend(struct device *dev)
+{
+       struct stm32_pwm *priv = dev_get_drvdata(dev);
+       unsigned int i;
+       u32 ccer, mask;
+
+       /* Look for active channels */
+       ccer = active_channels(priv);
+
+       for (i = 0; i < priv->chip.npwm; i++) {
+               mask = TIM_CCER_CC1E << (i * 4);
+               if (ccer & mask) {
+                       dev_err(dev, "PWM %u still in use by consumer %s\n",
+                               i, priv->chip.pwms[i].label);
+                       return -EBUSY;
+               }
+       }
+
+       return pinctrl_pm_select_sleep_state(dev);
+}
+
+static int __maybe_unused stm32_pwm_resume(struct device *dev)
+{
+       struct stm32_pwm *priv = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pinctrl_pm_select_default_state(dev);
+       if (ret)
+               return ret;
+
+       /* restore breakinput registers that may have been lost in low power */
+       return stm32_pwm_apply_breakinputs(priv);
+}
+
+static SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_resume);
+
 static const struct of_device_id stm32_pwm_of_match[] = {
        { .compatible = "st,stm32-pwm", },
        { /* end node */ },
@@ -659,6 +710,7 @@ static struct platform_driver stm32_pwm_driver = {
        .driver = {
                .name = "stm32-pwm",
                .of_match_table = stm32_pwm_of_match,
+               .pm = &stm32_pwm_pm_ops,
        },
 };
 module_platform_driver(stm32_pwm_driver);
index 6f5840a..581d232 100644 (file)
@@ -137,10 +137,10 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
 
        val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm));
 
-       tmp = prescaler * NSEC_PER_SEC * PWM_REG_DTY(val);
+       tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_DTY(val);
        state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
 
-       tmp = prescaler * NSEC_PER_SEC * PWM_REG_PRD(val);
+       tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_PRD(val);
        state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
 }
 
@@ -156,7 +156,6 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
        if (sun4i_pwm->data->has_prescaler_bypass) {
                /* First, test without any prescaler when available */
                prescaler = PWM_PRESCAL_MASK;
-               pval = 1;
                /*
                 * When not using any prescaler, the clock period in nanoseconds
                 * is not an integer so round it half up instead of
index 33c8d1e..f9e1064 100644 (file)
@@ -9,6 +9,8 @@
 #include <linux/rio.h>
 #include <linux/module.h>
 
+#include <linux/rio_drv.h>
+
 /*
  *  Wrappers for all RIO configuration access functions.  They just check
  *  alignment and call the low-level functions pointed to by rio_mport->ops.
index 2d99a37..7287415 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/rio.h>
 #include <linux/rio_ids.h>
+#include <linux/rio_drv.h>
 
 #include "rio.h"
 
index 7b07281..3ad7817 100644 (file)
@@ -129,7 +129,7 @@ config RESET_SCMI
 
 config RESET_SIMPLE
        bool "Simple Reset Controller Driver" if COMPILE_TEST
-       default ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED || ARCH_BITMAIN || ARC
+       default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC
        help
          This enables a simple reset controller driver for reset lines that
          that can be asserted and deasserted by toggling bits in a contiguous,
@@ -138,10 +138,11 @@ config RESET_SIMPLE
          Currently this driver supports:
           - Altera SoCFPGAs
           - ASPEED BMC SoCs
+          - Bitmain BM1880 SoC
+          - Realtek SoCs
           - RCC reset controller in STM32 MCUs
           - Allwinner SoCs
           - ZTE's zx2967 family
-          - Bitmain BM1880 SoC
 
 config RESET_STM32MP157
        bool "STM32MP157 Reset Driver" if COMPILE_TEST
index 3c9a64c..7597c70 100644 (file)
@@ -77,8 +77,10 @@ static const char *rcdev_name(struct reset_controller_dev *rcdev)
  * @rcdev: a pointer to the reset controller device
  * @reset_spec: reset line specifier as found in the device tree
  *
- * This simple translation function should be used for reset controllers
- * with 1:1 mapping, where reset lines can be indexed by number without gaps.
+ * This static translation function is used by default if of_xlate in
+ * :c:type:`reset_controller_dev` is not set. It is useful for all reset
+ * controllers with 1:1 mapping, where reset lines can be indexed by number
+ * without gaps.
  */
 static int of_reset_simple_xlate(struct reset_controller_dev *rcdev,
                          const struct of_phandle_args *reset_spec)
@@ -333,7 +335,6 @@ EXPORT_SYMBOL_GPL(reset_control_reset);
  * internal state to be reset, but must be prepared for this to happen.
  * Consumers must not use reset_control_reset on shared reset lines when
  * reset_control_(de)assert has been used.
- * return 0.
  *
  * If rstc is NULL it is an optional reset and the function will just
  * return 0.
@@ -392,7 +393,6 @@ EXPORT_SYMBOL_GPL(reset_control_assert);
  * After calling this function, the reset is guaranteed to be deasserted.
  * Consumers must not use reset_control_reset on shared reset lines when
  * reset_control_(de)assert has been used.
- * return 0.
  *
  * If rstc is NULL it is an optional reset and the function will just
  * return 0.
@@ -787,7 +787,7 @@ struct reset_control *__devm_reset_control_get(struct device *dev,
                return ERR_PTR(-ENOMEM);
 
        rstc = __reset_control_get(dev, id, index, shared, optional, acquired);
-       if (!IS_ERR(rstc)) {
+       if (!IS_ERR_OR_NULL(rstc)) {
                *ptr = rstc;
                devres_add(dev, ptr);
        } else {
@@ -861,8 +861,7 @@ static int of_reset_control_get_count(struct device_node *node)
  * @acquired: only one reset control may be acquired for a given controller
  *            and ID
  *
- * Returns pointer to allocated reset_control_array on success or
- * error on failure
+ * Returns pointer to allocated reset_control on success or error on failure
  */
 struct reset_control *
 of_reset_control_array_get(struct device_node *np, bool shared, bool optional,
@@ -915,8 +914,7 @@ EXPORT_SYMBOL_GPL(of_reset_control_array_get);
  * that just have to be asserted or deasserted, without any
  * requirements on the order.
  *
- * Returns pointer to allocated reset_control_array on success or
- * error on failure
+ * Returns pointer to allocated reset_control on success or error on failure
  */
 struct reset_control *
 devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
@@ -930,7 +928,7 @@ devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
                return ERR_PTR(-ENOMEM);
 
        rstc = of_reset_control_array_get(dev->of_node, shared, optional, true);
-       if (IS_ERR(rstc)) {
+       if (IS_ERR_OR_NULL(rstc)) {
                devres_free(devres);
                return rstc;
        }
index f690b18..a7d4445 100644 (file)
@@ -56,7 +56,7 @@ static int hi3660_reset_dev(struct reset_controller_dev *rcdev,
        return hi3660_reset_deassert(rcdev, idx);
 }
 
-static struct reset_control_ops hi3660_reset_ops = {
+static const struct reset_control_ops hi3660_reset_ops = {
        .reset    = hi3660_reset_dev,
        .assert   = hi3660_reset_assert,
        .deassert = hi3660_reset_deassert,
index a608f44..f213264 100644 (file)
@@ -91,12 +91,6 @@ static int brcmstb_reset_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!IS_ALIGNED(res->start, SW_INIT_BANK_SIZE) ||
-           !IS_ALIGNED(resource_size(res), SW_INIT_BANK_SIZE)) {
-               dev_err(kdev, "incorrect register range\n");
-               return -EINVAL;
-       }
-
        priv->base = devm_ioremap_resource(kdev, res);
        if (IS_ERR(priv->base))
                return PTR_ERR(priv->base);
index c53a218..1dc06e0 100644 (file)
@@ -19,6 +19,11 @@ struct meson_audio_arb_data {
        spinlock_t lock;
 };
 
+struct meson_audio_arb_match_data {
+       const unsigned int *reset_bits;
+       unsigned int reset_num;
+};
+
 #define ARB_GENERAL_BIT        31
 
 static const unsigned int axg_audio_arb_reset_bits[] = {
@@ -30,6 +35,27 @@ static const unsigned int axg_audio_arb_reset_bits[] = {
        [AXG_ARB_FRDDR_C]       = 6,
 };
 
+static const struct meson_audio_arb_match_data axg_audio_arb_match = {
+       .reset_bits = axg_audio_arb_reset_bits,
+       .reset_num = ARRAY_SIZE(axg_audio_arb_reset_bits),
+};
+
+static const unsigned int sm1_audio_arb_reset_bits[] = {
+       [AXG_ARB_TODDR_A]       = 0,
+       [AXG_ARB_TODDR_B]       = 1,
+       [AXG_ARB_TODDR_C]       = 2,
+       [AXG_ARB_FRDDR_A]       = 4,
+       [AXG_ARB_FRDDR_B]       = 5,
+       [AXG_ARB_FRDDR_C]       = 6,
+       [AXG_ARB_TODDR_D]       = 3,
+       [AXG_ARB_FRDDR_D]       = 7,
+};
+
+static const struct meson_audio_arb_match_data sm1_audio_arb_match = {
+       .reset_bits = sm1_audio_arb_reset_bits,
+       .reset_num = ARRAY_SIZE(sm1_audio_arb_reset_bits),
+};
+
 static int meson_audio_arb_update(struct reset_controller_dev *rcdev,
                                  unsigned long id, bool assert)
 {
@@ -82,7 +108,13 @@ static const struct reset_control_ops meson_audio_arb_rstc_ops = {
 };
 
 static const struct of_device_id meson_audio_arb_of_match[] = {
-       { .compatible = "amlogic,meson-axg-audio-arb", },
+       {
+               .compatible = "amlogic,meson-axg-audio-arb",
+               .data = &axg_audio_arb_match,
+       }, {
+               .compatible = "amlogic,meson-sm1-audio-arb",
+               .data = &sm1_audio_arb_match,
+       },
        {}
 };
 MODULE_DEVICE_TABLE(of, meson_audio_arb_of_match);
@@ -104,10 +136,15 @@ static int meson_audio_arb_remove(struct platform_device *pdev)
 static int meson_audio_arb_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
+       const struct meson_audio_arb_match_data *data;
        struct meson_audio_arb_data *arb;
        struct resource *res;
        int ret;
 
+       data = of_device_get_match_data(dev);
+       if (!data)
+               return -EINVAL;
+
        arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL);
        if (!arb)
                return -ENOMEM;
@@ -126,8 +163,8 @@ static int meson_audio_arb_probe(struct platform_device *pdev)
                return PTR_ERR(arb->regs);
 
        spin_lock_init(&arb->lock);
-       arb->reset_bits = axg_audio_arb_reset_bits;
-       arb->rstc.nr_resets = ARRAY_SIZE(axg_audio_arb_reset_bits);
+       arb->reset_bits = data->reset_bits;
+       arb->rstc.nr_resets = data->reset_num;
        arb->rstc.ops = &meson_audio_arb_rstc_ops;
        arb->rstc.of_node = dev->of_node;
        arb->rstc.owner = THIS_MODULE;
index 7d05d76..94d7ba8 100644 (file)
 #include <linux/types.h>
 #include <linux/of_device.h>
 
-#define REG_COUNT      8
 #define BITS_PER_REG   32
-#define LEVEL_OFFSET   0x7c
+
+struct meson_reset_param {
+       int reg_count;
+       int level_offset;
+};
 
 struct meson_reset {
        void __iomem *reg_base;
+       const struct meson_reset_param *param;
        struct reset_controller_dev rcdev;
        spinlock_t lock;
 };
@@ -46,10 +50,12 @@ static int meson_reset_level(struct reset_controller_dev *rcdev,
                container_of(rcdev, struct meson_reset, rcdev);
        unsigned int bank = id / BITS_PER_REG;
        unsigned int offset = id % BITS_PER_REG;
-       void __iomem *reg_addr = data->reg_base + LEVEL_OFFSET + (bank << 2);
+       void __iomem *reg_addr;
        unsigned long flags;
        u32 reg;
 
+       reg_addr = data->reg_base + data->param->level_offset + (bank << 2);
+
        spin_lock_irqsave(&data->lock, flags);
 
        reg = readl(reg_addr);
@@ -81,10 +87,21 @@ static const struct reset_control_ops meson_reset_ops = {
        .deassert       = meson_reset_deassert,
 };
 
+static const struct meson_reset_param meson8b_param = {
+       .reg_count      = 8,
+       .level_offset   = 0x7c,
+};
+
+static const struct meson_reset_param meson_a1_param = {
+       .reg_count      = 3,
+       .level_offset   = 0x40,
+};
+
 static const struct of_device_id meson_reset_dt_ids[] = {
-        { .compatible = "amlogic,meson8b-reset" },
-        { .compatible = "amlogic,meson-gxbb-reset" },
-        { .compatible = "amlogic,meson-axg-reset" },
+        { .compatible = "amlogic,meson8b-reset",    .data = &meson8b_param},
+        { .compatible = "amlogic,meson-gxbb-reset", .data = &meson8b_param},
+        { .compatible = "amlogic,meson-axg-reset",  .data = &meson8b_param},
+        { .compatible = "amlogic,meson-a1-reset",   .data = &meson_a1_param},
         { /* sentinel */ },
 };
 
@@ -102,12 +119,16 @@ static int meson_reset_probe(struct platform_device *pdev)
        if (IS_ERR(data->reg_base))
                return PTR_ERR(data->reg_base);
 
+       data->param = of_device_get_match_data(&pdev->dev);
+       if (!data->param)
+               return -ENODEV;
+
        platform_set_drvdata(pdev, data);
 
        spin_lock_init(&data->lock);
 
        data->rcdev.owner = THIS_MODULE;
-       data->rcdev.nr_resets = REG_COUNT * BITS_PER_REG;
+       data->rcdev.nr_resets = data->param->reg_count * BITS_PER_REG;
        data->rcdev.ops = &meson_reset_ops;
        data->rcdev.of_node = pdev->dev.of_node;
 
index a45923f..2b188b3 100644 (file)
@@ -141,6 +141,10 @@ static const struct of_device_id uniphier_glue_reset_match[] = {
                .data = &uniphier_pro4_data,
        },
        {
+               .compatible = "socionext,uniphier-pro5-usb3-reset",
+               .data = &uniphier_pro4_data,
+       },
+       {
                .compatible = "socionext,uniphier-pxs2-usb3-reset",
                .data = &uniphier_pxs2_data,
        },
index 99e75d9..0144075 100644 (file)
@@ -64,7 +64,7 @@ static int zynqmp_reset_reset(struct reset_controller_dev *rcdev,
                                            PM_RESET_ACTION_PULSE);
 }
 
-static struct reset_control_ops zynqmp_reset_ops = {
+static const struct reset_control_ops zynqmp_reset_ops = {
        .reset = zynqmp_reset_reset,
        .assert = zynqmp_reset_assert,
        .deassert = zynqmp_reset_deassert,
index 293dd99..871d447 100644 (file)
@@ -480,6 +480,7 @@ struct qeth_card_stats {
 
        u64 rx_dropped_nomem;
        u64 rx_dropped_notsupp;
+       u64 rx_dropped_runt;
 
        /* rtnl_link_stats64 */
        u64 rx_packets;
@@ -627,6 +628,7 @@ struct qeth_ipato {
 
 struct qeth_channel {
        struct ccw_device *ccwdev;
+       struct qeth_cmd_buffer *active_cmd;
        enum qeth_channel_states state;
        atomic_t irq_pending;
 };
@@ -1037,6 +1039,8 @@ int qeth_do_run_thread(struct qeth_card *, unsigned long);
 void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long);
 void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
 int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok);
+int qeth_stop_channel(struct qeth_channel *channel);
+
 void qeth_print_status_message(struct qeth_card *);
 int qeth_init_qdio_queues(struct qeth_card *);
 int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
index efcbe60..33a62a6 100644 (file)
@@ -515,7 +515,9 @@ static int __qeth_issue_next_read(struct qeth_card *card)
 
        QETH_CARD_TEXT(card, 6, "noirqpnd");
        rc = ccw_device_start(channel->ccwdev, ccw, (addr_t) iob, 0, 0);
-       if (rc) {
+       if (!rc) {
+               channel->active_cmd = iob;
+       } else {
                QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n",
                                 rc, CARD_DEVID(card));
                atomic_set(&channel->irq_pending, 0);
@@ -986,8 +988,21 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                QETH_CARD_TEXT(card, 5, "data");
        }
 
-       if (qeth_intparm_is_iob(intparm))
-               iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
+       if (intparm == 0) {
+               QETH_CARD_TEXT(card, 5, "irqunsol");
+       } else if ((addr_t)intparm != (addr_t)channel->active_cmd) {
+               QETH_CARD_TEXT(card, 5, "irqunexp");
+
+               dev_err(&cdev->dev,
+                       "Received IRQ with intparm %lx, expected %px\n",
+                       intparm, channel->active_cmd);
+               if (channel->active_cmd)
+                       qeth_cancel_cmd(channel->active_cmd, -EIO);
+       } else {
+               iob = (struct qeth_cmd_buffer *) (addr_t)intparm;
+       }
+
+       channel->active_cmd = NULL;
 
        rc = qeth_check_irb_error(card, cdev, irb);
        if (rc) {
@@ -1007,15 +1022,10 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
        if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC))
                channel->state = CH_STATE_HALTED;
 
-       if (intparm == QETH_CLEAR_CHANNEL_PARM) {
-               QETH_CARD_TEXT(card, 6, "clrchpar");
-               /* we don't have to handle this further */
-               intparm = 0;
-       }
-       if (intparm == QETH_HALT_CHANNEL_PARM) {
-               QETH_CARD_TEXT(card, 6, "hltchpar");
-               /* we don't have to handle this further */
-               intparm = 0;
+       if (iob && (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC |
+                                         SCSW_FCTL_HALT_FUNC))) {
+               qeth_cancel_cmd(iob, -ECANCELED);
+               iob = NULL;
        }
 
        cstat = irb->scsw.cmd.cstat;
@@ -1408,7 +1418,7 @@ static int qeth_clear_channel(struct qeth_card *card,
 
        QETH_CARD_TEXT(card, 3, "clearch");
        spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
-       rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM);
+       rc = ccw_device_clear(channel->ccwdev, (addr_t)channel->active_cmd);
        spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
 
        if (rc)
@@ -1430,7 +1440,7 @@ static int qeth_halt_channel(struct qeth_card *card,
 
        QETH_CARD_TEXT(card, 3, "haltch");
        spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
-       rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM);
+       rc = ccw_device_halt(channel->ccwdev, (addr_t)channel->active_cmd);
        spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
 
        if (rc)
@@ -1444,6 +1454,25 @@ static int qeth_halt_channel(struct qeth_card *card,
        return 0;
 }
 
+int qeth_stop_channel(struct qeth_channel *channel)
+{
+       struct ccw_device *cdev = channel->ccwdev;
+       int rc;
+
+       rc = ccw_device_set_offline(cdev);
+
+       spin_lock_irq(get_ccwdev_lock(cdev));
+       if (channel->active_cmd) {
+               dev_err(&cdev->dev, "Stopped channel while cmd %px was still active\n",
+                       channel->active_cmd);
+               channel->active_cmd = NULL;
+       }
+       spin_unlock_irq(get_ccwdev_lock(cdev));
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_stop_channel);
+
 static int qeth_halt_channels(struct qeth_card *card)
 {
        int rc1 = 0, rc2 = 0, rc3 = 0;
@@ -1746,6 +1775,8 @@ static int qeth_send_control_data(struct qeth_card *card,
        spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
        rc = ccw_device_start_timeout(channel->ccwdev, __ccw_from_cmd(iob),
                                      (addr_t) iob, 0, 0, timeout);
+       if (!rc)
+               channel->active_cmd = iob;
        spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
        if (rc) {
                QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n",
@@ -4667,12 +4698,12 @@ EXPORT_SYMBOL_GPL(qeth_vm_request_mac);
 
 static void qeth_determine_capabilities(struct qeth_card *card)
 {
+       struct qeth_channel *channel = &card->data;
+       struct ccw_device *ddev = channel->ccwdev;
        int rc;
-       struct ccw_device *ddev;
        int ddev_offline = 0;
 
        QETH_CARD_TEXT(card, 2, "detcapab");
-       ddev = CARD_DDEV(card);
        if (!ddev->online) {
                ddev_offline = 1;
                rc = ccw_device_set_online(ddev);
@@ -4711,7 +4742,7 @@ static void qeth_determine_capabilities(struct qeth_card *card)
 
 out_offline:
        if (ddev_offline == 1)
-               ccw_device_set_offline(ddev);
+               qeth_stop_channel(channel);
 out:
        return;
 }
@@ -4748,7 +4779,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
 
        QETH_CARD_TEXT(card, 2, "qdioest");
 
-       qib_param_field = kzalloc(FIELD_SIZEOF(struct qib, parm), GFP_KERNEL);
+       qib_param_field = kzalloc(sizeof_field(struct qib, parm), GFP_KERNEL);
        if (!qib_param_field) {
                rc =  -ENOMEM;
                goto out_free_nothing;
@@ -4911,9 +4942,9 @@ retry:
                QETH_DBF_MESSAGE(2, "Retrying to do IDX activates on device %x.\n",
                                 CARD_DEVID(card));
        rc = qeth_qdio_clear_card(card, !IS_IQD(card));
-       ccw_device_set_offline(CARD_DDEV(card));
-       ccw_device_set_offline(CARD_WDEV(card));
-       ccw_device_set_offline(CARD_RDEV(card));
+       qeth_stop_channel(&card->data);
+       qeth_stop_channel(&card->write);
+       qeth_stop_channel(&card->read);
        qdio_free(CARD_DDEV(card));
        rc = ccw_device_set_online(CARD_RDEV(card));
        if (rc)
@@ -5028,27 +5059,15 @@ out:
 }
 EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card);
 
-static void qeth_create_skb_frag(struct qdio_buffer_element *element,
-                                struct sk_buff *skb, int offset, int data_len)
+static void qeth_create_skb_frag(struct sk_buff *skb, char *data, int data_len)
 {
-       struct page *page = virt_to_page(element->addr);
+       struct page *page = virt_to_page(data);
        unsigned int next_frag;
 
-       /* first fill the linear space */
-       if (!skb->len) {
-               unsigned int linear = min(data_len, skb_tailroom(skb));
-
-               skb_put_data(skb, element->addr + offset, linear);
-               data_len -= linear;
-               if (!data_len)
-                       return;
-               offset += linear;
-               /* fall through to add page frag for remaining data */
-       }
-
        next_frag = skb_shinfo(skb)->nr_frags;
        get_page(page);
-       skb_add_rx_frag(skb, next_frag, page, offset, data_len, data_len);
+       skb_add_rx_frag(skb, next_frag, page, offset_in_page(data), data_len,
+                       data_len);
 }
 
 static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale)
@@ -5063,13 +5082,12 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
 {
        struct qdio_buffer_element *element = *__element;
        struct qdio_buffer *buffer = qethbuffer->buffer;
+       unsigned int linear_len = 0;
        int offset = *__offset;
        bool use_rx_sg = false;
        unsigned int headroom;
        struct sk_buff *skb;
        int skb_len = 0;
-       void *data_ptr;
-       int data_len;
 
 next_packet:
        /* qeth_hdr must not cross element boundaries */
@@ -5082,29 +5100,41 @@ next_packet:
        *hdr = element->addr + offset;
 
        offset += sizeof(struct qeth_hdr);
+       skb = NULL;
+
        switch ((*hdr)->hdr.l2.id) {
        case QETH_HEADER_TYPE_LAYER2:
                skb_len = (*hdr)->hdr.l2.pkt_length;
+               linear_len = ETH_HLEN;
                headroom = 0;
                break;
        case QETH_HEADER_TYPE_LAYER3:
                skb_len = (*hdr)->hdr.l3.length;
                if (!IS_LAYER3(card)) {
                        QETH_CARD_STAT_INC(card, rx_dropped_notsupp);
-                       skb = NULL;
                        goto walk_packet;
                }
 
+               if ((*hdr)->hdr.l3.flags & QETH_HDR_PASSTHRU) {
+                       linear_len = ETH_HLEN;
+                       headroom = 0;
+                       break;
+               }
+
+               if ((*hdr)->hdr.l3.flags & QETH_HDR_IPV6)
+                       linear_len = sizeof(struct ipv6hdr);
+               else
+                       linear_len = sizeof(struct iphdr);
                headroom = ETH_HLEN;
                break;
        case QETH_HEADER_TYPE_OSN:
                skb_len = (*hdr)->hdr.osn.pdu_length;
                if (!IS_OSN(card)) {
                        QETH_CARD_STAT_INC(card, rx_dropped_notsupp);
-                       skb = NULL;
                        goto walk_packet;
                }
 
+               linear_len = skb_len;
                headroom = sizeof(struct qeth_hdr);
                break;
        default:
@@ -5117,8 +5147,10 @@ next_packet:
                return NULL;
        }
 
-       if (!skb_len)
-               return NULL;
+       if (skb_len < linear_len) {
+               QETH_CARD_STAT_INC(card, rx_dropped_runt);
+               goto walk_packet;
+       }
 
        use_rx_sg = (card->options.cq == QETH_CQ_ENABLED) ||
                    ((skb_len >= card->options.rx_sg_cb) &&
@@ -5130,9 +5162,9 @@ next_packet:
                skb = qethbuffer->rx_skb;
                qethbuffer->rx_skb = NULL;
        } else {
-               unsigned int linear = (use_rx_sg) ? QETH_RX_PULL_LEN : skb_len;
-
-               skb = napi_alloc_skb(&card->napi, linear + headroom);
+               if (!use_rx_sg)
+                       linear_len = skb_len;
+               skb = napi_alloc_skb(&card->napi, linear_len + headroom);
        }
 
        if (!skb)
@@ -5141,18 +5173,32 @@ next_packet:
                skb_reserve(skb, headroom);
 
 walk_packet:
-       data_ptr = element->addr + offset;
        while (skb_len) {
-               data_len = min(skb_len, (int)(element->length - offset));
+               int data_len = min(skb_len, (int)(element->length - offset));
+               char *data = element->addr + offset;
+
+               skb_len -= data_len;
+               offset += data_len;
 
+               /* Extract data from current element: */
                if (skb && data_len) {
-                       if (use_rx_sg)
-                               qeth_create_skb_frag(element, skb, offset,
-                                                    data_len);
-                       else
-                               skb_put_data(skb, data_ptr, data_len);
+                       if (linear_len) {
+                               unsigned int copy_len;
+
+                               copy_len = min_t(unsigned int, linear_len,
+                                                data_len);
+
+                               skb_put_data(skb, data, copy_len);
+                               linear_len -= copy_len;
+                               data_len -= copy_len;
+                               data += copy_len;
+                       }
+
+                       if (data_len)
+                               qeth_create_skb_frag(skb, data, data_len);
                }
-               skb_len -= data_len;
+
+               /* Step forward to next element: */
                if (skb_len) {
                        if (qeth_is_last_sbale(element)) {
                                QETH_CARD_TEXT(card, 4, "unexeob");
@@ -5166,9 +5212,6 @@ walk_packet:
                        }
                        element++;
                        offset = 0;
-                       data_ptr = element->addr;
-               } else {
-                       offset += data_len;
                }
        }
 
@@ -6268,7 +6311,8 @@ void qeth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
                           card->stats.rx_frame_errors +
                           card->stats.rx_fifo_errors;
        stats->rx_dropped = card->stats.rx_dropped_nomem +
-                           card->stats.rx_dropped_notsupp;
+                           card->stats.rx_dropped_notsupp +
+                           card->stats.rx_dropped_runt;
        stats->multicast = card->stats.rx_multicast;
        stats->rx_length_errors = card->stats.rx_length_errors;
        stats->rx_frame_errors = card->stats.rx_frame_errors;
index 53fcf66..c1ecce9 100644 (file)
@@ -29,20 +29,6 @@ extern unsigned char IPA_PDU_HEADER[];
 #define QETH_TIMEOUT           (10 * HZ)
 #define QETH_IPA_TIMEOUT       (45 * HZ)
 
-#define QETH_CLEAR_CHANNEL_PARM        -10
-#define QETH_HALT_CHANNEL_PARM -11
-
-static inline bool qeth_intparm_is_iob(unsigned long intparm)
-{
-       switch (intparm) {
-       case QETH_CLEAR_CHANNEL_PARM:
-       case QETH_HALT_CHANNEL_PARM:
-       case 0:
-               return false;
-       }
-       return true;
-}
-
 /*****************************************************************************/
 /* IP Assist related definitions                                             */
 /*****************************************************************************/
@@ -435,7 +421,7 @@ struct qeth_ipacmd_setassparms {
        } data;
 } __attribute__ ((packed));
 
-#define SETASS_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setassparms,\
+#define SETASS_DATA_SIZEOF(field) sizeof_field(struct qeth_ipacmd_setassparms,\
                                               data.field)
 
 /* SETRTG IPA Command:    ****************************************************/
@@ -549,7 +535,7 @@ struct qeth_ipacmd_setadpparms {
        } data;
 } __attribute__ ((packed));
 
-#define SETADP_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setadpparms,\
+#define SETADP_DATA_SIZEOF(field) sizeof_field(struct qeth_ipacmd_setadpparms,\
                                               data.field)
 
 /* CREATE_ADDR IPA Command:    ***********************************************/
@@ -662,7 +648,7 @@ struct qeth_ipacmd_vnicc {
        } data;
 };
 
-#define VNICC_DATA_SIZEOF(field)       FIELD_SIZEOF(struct qeth_ipacmd_vnicc,\
+#define VNICC_DATA_SIZEOF(field)       sizeof_field(struct qeth_ipacmd_vnicc,\
                                                     data.field)
 
 /* SETBRIDGEPORT IPA Command:   *********************************************/
@@ -743,7 +729,7 @@ struct qeth_ipacmd_setbridgeport {
        } data;
 } __packed;
 
-#define SBP_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setbridgeport,\
+#define SBP_DATA_SIZEOF(field) sizeof_field(struct qeth_ipacmd_setbridgeport,\
                                             data.field)
 
 /* ADDRESS_CHANGE_NOTIFICATION adapter-initiated "command" *******************/
@@ -804,7 +790,7 @@ struct qeth_ipa_cmd {
        } data;
 } __attribute__ ((packed));
 
-#define IPA_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipa_cmd, data.field)
+#define IPA_DATA_SIZEOF(field) sizeof_field(struct qeth_ipa_cmd, data.field)
 
 /*
  * special command for ARP processing.
index f7485c6..ab59bc9 100644 (file)
@@ -51,6 +51,7 @@ static const struct qeth_stats card_stats[] = {
        QETH_CARD_STAT("rx0 SG page allocs", rx_sg_alloc_page),
        QETH_CARD_STAT("rx0 dropped, no memory", rx_dropped_nomem),
        QETH_CARD_STAT("rx0 dropped, bad format", rx_dropped_notsupp),
+       QETH_CARD_STAT("rx0 dropped, runt", rx_dropped_runt),
 };
 
 #define TXQ_STATS_LEN  ARRAY_SIZE(txq_stats)
index 989935d..9086bc0 100644 (file)
@@ -845,9 +845,9 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev)
 
 out_remove:
        qeth_l2_stop_card(card);
-       ccw_device_set_offline(CARD_DDEV(card));
-       ccw_device_set_offline(CARD_WDEV(card));
-       ccw_device_set_offline(CARD_RDEV(card));
+       qeth_stop_channel(&card->data);
+       qeth_stop_channel(&card->write);
+       qeth_stop_channel(&card->read);
        qdio_free(CARD_DDEV(card));
 
        mutex_unlock(&card->conf_mutex);
@@ -878,9 +878,9 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
        rtnl_unlock();
 
        qeth_l2_stop_card(card);
-       rc  = ccw_device_set_offline(CARD_DDEV(card));
-       rc2 = ccw_device_set_offline(CARD_WDEV(card));
-       rc3 = ccw_device_set_offline(CARD_RDEV(card));
+       rc  = qeth_stop_channel(&card->data);
+       rc2 = qeth_stop_channel(&card->write);
+       rc3 = qeth_stop_channel(&card->read);
        if (!rc)
                rc = (rc2) ? rc2 : rc3;
        if (rc)
index e7ce73b..2712633 100644 (file)
@@ -2259,9 +2259,9 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev)
        return 0;
 out_remove:
        qeth_l3_stop_card(card);
-       ccw_device_set_offline(CARD_DDEV(card));
-       ccw_device_set_offline(CARD_WDEV(card));
-       ccw_device_set_offline(CARD_RDEV(card));
+       qeth_stop_channel(&card->data);
+       qeth_stop_channel(&card->write);
+       qeth_stop_channel(&card->read);
        qdio_free(CARD_DDEV(card));
 
        mutex_unlock(&card->conf_mutex);
@@ -2297,9 +2297,10 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
                call_netdevice_notifiers(NETDEV_REBOOT, card->dev);
                rtnl_unlock();
        }
-       rc  = ccw_device_set_offline(CARD_DDEV(card));
-       rc2 = ccw_device_set_offline(CARD_WDEV(card));
-       rc3 = ccw_device_set_offline(CARD_RDEV(card));
+
+       rc  = qeth_stop_channel(&card->data);
+       rc2 = qeth_stop_channel(&card->write);
+       rc3 = qeth_stop_channel(&card->read);
        if (!rc)
                rc = (rc2) ? rc2 : rc3;
        if (rc)
index e36608c..33dbc05 100644 (file)
@@ -535,7 +535,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
        if ((le32_to_cpu(get_name_reply->status) == CT_OK)
         && (get_name_reply->data[0] != '\0')) {
                char *sp = get_name_reply->data;
-               int data_size = FIELD_SIZEOF(struct aac_get_name_resp, data);
+               int data_size = sizeof_field(struct aac_get_name_resp, data);
 
                sp[data_size - 1] = '\0';
                while (*sp == ' ')
@@ -574,7 +574,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
 
        dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 
-       data_size = FIELD_SIZEOF(struct aac_get_name_resp, data);
+       data_size = sizeof_field(struct aac_get_name_resp, data);
 
        cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
 
index 063dccc..5f9f0b1 100644 (file)
@@ -1300,7 +1300,7 @@ struct be_cmd_get_port_name {
 
 /* Returns the number of items in the field array. */
 #define BE_NUMBER_OF_FIELD(_type_, _field_)    \
-       (FIELD_SIZEOF(_type_, _field_)/sizeof((((_type_ *)0)->_field_[0])))\
+       (sizeof_field(_type_, _field_)/sizeof((((_type_ *)0)->_field_[0])))\
 
 /**
  * Different types of iSCSI completions to host driver for both initiator
index 0d044c1..c4e4b01 100644 (file)
@@ -2746,7 +2746,7 @@ static int __init libcxgbi_init_module(void)
 {
        pr_info("%s", version);
 
-       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, cb) <
+       BUILD_BUG_ON(sizeof_field(struct sk_buff, cb) <
                     sizeof(struct cxgbi_skb_cb));
        return 0;
 }
index a929fe7..54b8c6f 100644 (file)
@@ -2354,7 +2354,6 @@ static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi,
 {
        struct iu_entry *iue = cmd->iue;
        struct srp_i_logout *log_out = &vio_iu(iue)->srp.i_logout;
-       long rc = ADAPT_SUCCESS;
 
        if ((vscsi->debit > 0) || !list_empty(&vscsi->schedule_q) ||
            !list_empty(&vscsi->waiting_rsp)) {
@@ -2370,7 +2369,7 @@ static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi,
                ibmvscsis_post_disconnect(vscsi, WAIT_IDLE, 0);
        }
 
-       return rc;
+       return ADAPT_SUCCESS;
 }
 
 /* Called with intr lock held */
index ebd47c0..70b99c0 100644 (file)
@@ -1945,7 +1945,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 
        ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc);
 
-       spin_lock(&session->frwd_lock);
+       spin_lock_bh(&session->frwd_lock);
        task = (struct iscsi_task *)sc->SCp.ptr;
        if (!task) {
                /*
@@ -2072,7 +2072,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 done:
        if (task)
                task->last_timeout = jiffies;
-       spin_unlock(&session->frwd_lock);
+       spin_unlock_bh(&session->frwd_lock);
        ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
                     "timer reset" : "shutdown or nh");
        return rc;
index f47b4b2..d7302c2 100644 (file)
@@ -81,12 +81,21 @@ static int sas_get_port_device(struct asd_sas_port *port)
                else
                        dev->dev_type = SAS_SATA_DEV;
                dev->tproto = SAS_PROTOCOL_SATA;
-       } else {
+       } else if (port->oob_mode == SAS_OOB_MODE) {
                struct sas_identify_frame *id =
                        (struct sas_identify_frame *) dev->frame_rcvd;
                dev->dev_type = id->dev_type;
                dev->iproto = id->initiator_bits;
                dev->tproto = id->target_bits;
+       } else {
+               /* If the oob mode is OOB_NOT_CONNECTED, the port is
+                * disconnected due to race with PHY down. We cannot
+                * continue to discover this port
+                */
+               sas_put_device(dev);
+               pr_warn("Port %016llx is disconnected when discovering\n",
+                       SAS_ADDR(port->attached_sas_addr));
+               return -ENODEV;
        }
 
        sas_init_dev(dev);
index d4e1b12..0ea03ae 100644 (file)
@@ -4489,12 +4489,6 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job,
        phba->mbox_ext_buf_ctx.seqNum++;
        nemb_tp = phba->mbox_ext_buf_ctx.nembType;
 
-       dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
-       if (!dd_data) {
-               rc = -ENOMEM;
-               goto job_error;
-       }
-
        pbuf = (uint8_t *)dmabuf->virt;
        size = job->request_payload.payload_len;
        sg_copy_to_buffer(job->request_payload.sg_list,
@@ -4531,6 +4525,13 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job,
                                "2968 SLI_CONFIG ext-buffer wr all %d "
                                "ebuffers received\n",
                                phba->mbox_ext_buf_ctx.numBuf);
+
+               dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+               if (!dd_data) {
+                       rc = -ENOMEM;
+                       goto job_error;
+               }
+
                /* mailbox command structure for base driver */
                pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
                if (!pmboxq) {
@@ -4579,6 +4580,8 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job,
        return SLI_CONFIG_HANDLED;
 
 job_error:
+       if (pmboxq)
+               mempool_free(pmboxq, phba->mbox_mem_pool);
        lpfc_bsg_dma_page_free(phba, dmabuf);
        kfree(dd_data);
 
index dc6f7c4..6298b17 100644 (file)
@@ -6460,7 +6460,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
        u32 if_fam;
 
        phba->sli4_hba.num_present_cpu = lpfc_present_cpu;
-       phba->sli4_hba.num_possible_cpu = num_possible_cpus();
+       phba->sli4_hba.num_possible_cpu = cpumask_last(cpu_possible_mask) + 1;
        phba->sli4_hba.curr_disp_cpu = 0;
        lpfc_cpumask_of_node_init(phba);
 
index db4a04a..f6c8963 100644 (file)
@@ -1985,6 +1985,8 @@ out_unlock:
 
 /* Declare and initialization an instance of the FC NVME template. */
 static struct nvme_fc_port_template lpfc_nvme_template = {
+       .module = THIS_MODULE,
+
        /* initiator-based functions */
        .localport_delete  = lpfc_nvme_localport_delete,
        .remoteport_delete = lpfc_nvme_remoteport_delete,
index c40fbea..a4bc814 100644 (file)
@@ -199,7 +199,7 @@ static bool support_nvme_encapsulation;
 static bool support_pci_lane_margining;
 
 /* define lock for aen poll */
-spinlock_t poll_aen_lock;
+static spinlock_t poll_aen_lock;
 
 extern struct dentry *megasas_debugfs_root;
 extern void megasas_init_debugfs(void);
index 1960113..98dcdbd 100644 (file)
@@ -37,7 +37,6 @@
  * POSSIBILITY OF SUCH DAMAGES.
  *
  */
- #include <linux/version.h>
  #include <linux/slab.h>
  #include "pm8001_sas.h"
  #include "pm80xx_hwi.h"
@@ -348,7 +347,7 @@ moreData:
                        do {
                                reg_val = pm8001_mr32(fatal_table_address,
                                        MPI_FATAL_EDUMP_TABLE_STATUS);
-                       } while (((reg_val != 2) || (reg_val != 3)) &&
+                       } while (((reg_val != 2) && (reg_val != 3)) &&
                                        time_before(jiffies, start));
 
                        if (reg_val < 2) {
index ae97e2f..d7e7043 100644 (file)
@@ -178,6 +178,7 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj,
 
        faddr = ha->flt_region_nvram;
        if (IS_QLA28XX(ha)) {
+               qla28xx_get_aux_images(vha, &active_regions);
                if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
                        faddr = ha->flt_region_nvram_sec;
        }
index 99f0a1a..cbaf178 100644 (file)
@@ -2399,7 +2399,7 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
        struct qla_active_regions regions = { };
        struct active_regions active_regions = { };
 
-       qla28xx_get_aux_images(vha, &active_regions);
+       qla27xx_get_active_image(vha, &active_regions);
        regions.global_image = active_regions.global;
 
        if (IS_QLA28XX(ha)) {
index 460f443..2edd9f7 100644 (file)
@@ -2401,6 +2401,7 @@ typedef struct fc_port {
        unsigned int id_changed:1;
        unsigned int scan_needed:1;
        unsigned int n2n_flag:1;
+       unsigned int explicit_logout:1;
 
        struct completion nvme_del_done;
        uint32_t nvme_prli_service_param;
index 59f6903..9dc09c1 100644 (file)
@@ -1523,6 +1523,10 @@ struct qla_flt_header {
 #define FLT_REG_NVRAM_SEC_28XX_1       0x10F
 #define FLT_REG_NVRAM_SEC_28XX_2       0x111
 #define FLT_REG_NVRAM_SEC_28XX_3       0x113
+#define FLT_REG_MPI_PRI_28XX           0xD3
+#define FLT_REG_MPI_SEC_28XX           0xF0
+#define FLT_REG_PEP_PRI_28XX           0xD1
+#define FLT_REG_PEP_SEC_28XX           0xF1
 
 struct qla_flt_region {
        uint16_t code;
index 6723068..446a9d6 100644 (file)
@@ -3587,12 +3587,23 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
                if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
                        set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
                        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+                       goto out;
                } else {
-                       ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
+                       ql_dbg(ql_dbg_disc, vha, 0xffff,
                            "%s: Fabric scan failed for %d retries.\n",
                            __func__, vha->scan.scan_retry);
+                       /*
+                        * Unable to scan any rports. logout loop below
+                        * will unregister all sessions.
+                        */
+                       list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                               if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) {
+                                       fcport->scan_state = QLA_FCPORT_SCAN;
+                                       fcport->logout_on_delete = 0;
+                               }
+                       }
+                       goto login_logout;
                }
-               goto out;
        }
        vha->scan.scan_retry = 0;
 
@@ -3670,6 +3681,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
                    dup_cnt);
        }
 
+login_logout:
        /*
         * Logout all previous fabric dev marked lost, except FCP2 devices.
         */
index 1dbee88..aa52041 100644 (file)
@@ -533,6 +533,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
 
        e->u.fcport.fcport = fcport;
        fcport->flags |= FCF_ASYNC_ACTIVE;
+       fcport->disc_state = DSC_LOGIN_PEND;
        return qla2x00_post_work(vha, e);
 }
 
@@ -1526,8 +1527,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
                }
        }
 
-       /* for pure Target Mode. Login will not be initiated */
-       if (vha->host->active_mode == MODE_TARGET)
+       /* Target won't initiate port login if fabric is present */
+       if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw))
                return 0;
 
        if (fcport->flags & FCF_ASYNC_SENT) {
@@ -1719,6 +1720,10 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
 void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
                                      struct event_arg *ea)
 {
+       /* for pure Target Mode, PRLI will not be initiated */
+       if (vha->host->active_mode == MODE_TARGET)
+               return;
+
        ql_dbg(ql_dbg_disc, vha, 0x2118,
            "%s %d %8phC post PRLI\n",
            __func__, __LINE__, ea->fcport->port_name);
@@ -4852,6 +4857,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
        }
 
        INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn);
+       INIT_WORK(&fcport->free_work, qlt_free_session_done);
        INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
        INIT_LIST_HEAD(&fcport->gnl_entry);
        INIT_LIST_HEAD(&fcport->list);
@@ -4930,14 +4936,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
                set_bit(RSCN_UPDATE, &flags);
                clear_bit(LOCAL_LOOP_UPDATE, &flags);
 
-       } else if (ha->current_topology == ISP_CFG_N) {
-               clear_bit(RSCN_UPDATE, &flags);
-               if (qla_tgt_mode_enabled(vha)) {
-                       /* allow the other side to start the login */
-                       clear_bit(LOCAL_LOOP_UPDATE, &flags);
-                       set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
-               }
-       } else if (ha->current_topology == ISP_CFG_NL) {
+       } else if (ha->current_topology == ISP_CFG_NL ||
+                  ha->current_topology == ISP_CFG_N) {
                clear_bit(RSCN_UPDATE, &flags);
                set_bit(LOCAL_LOOP_UPDATE, &flags);
        } else if (!vha->flags.online ||
@@ -5054,7 +5054,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
                                memcpy(&ha->plogi_els_payld.data,
                                    (void *)ha->init_cb,
                                    sizeof(ha->plogi_els_payld.data));
-                               set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
                        } else {
                                ql_dbg(ql_dbg_init, vha, 0x00d1,
                                    "PLOGI ELS param read fail.\n");
@@ -5898,8 +5897,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
                if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
                        break;
 
-               if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 ||
-                   (fcport->flags & FCF_LOGIN_NEEDED) == 0)
+               if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
                        continue;
 
                if (fcport->scan_state == QLA_FCPORT_SCAN) {
@@ -5922,7 +5920,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
                        }
                }
 
-               if (fcport->scan_state == QLA_FCPORT_FOUND)
+               if (fcport->scan_state == QLA_FCPORT_FOUND &&
+                   (fcport->flags & FCF_LOGIN_NEEDED) != 0)
                        qla24xx_fcport_handle_login(vha, fcport);
        }
        return (rval);
index b25f87f..8b050f0 100644 (file)
@@ -2405,11 +2405,19 @@ qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
 static void
 qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
 {
+       u16 control_flags = LCF_COMMAND_LOGO;
        logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
-       logio->control_flags =
-           cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
-       if (!sp->fcport->keep_nport_handle)
-               logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT);
+
+       if (sp->fcport->explicit_logout) {
+               control_flags |= LCF_EXPL_LOGO|LCF_FREE_NPORT;
+       } else {
+               control_flags |= LCF_IMPL_LOGO;
+
+               if (!sp->fcport->keep_nport_handle)
+                       control_flags |= LCF_FREE_NPORT;
+       }
+
+       logio->control_flags = cpu_to_le16(control_flags);
        logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
        logio->port_id[0] = sp->fcport->d_id.b.al_pa;
        logio->port_id[1] = sp->fcport->d_id.b.area;
@@ -2617,6 +2625,10 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
 
        memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld,
            sizeof(struct els_logo_payload));
+       ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3075, "LOGO buffer:");
+       ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x010a,
+                      elsio->u.els_logo.els_logo_pyld,
+                      sizeof(*elsio->u.els_logo.els_logo_pyld));
 
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
@@ -2676,7 +2688,8 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
                ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073,
                    "PLOGI ELS IOCB:\n");
                ql_dump_buffer(ql_log_info, vha, 0x0109,
-                   (uint8_t *)els_iocb, 0x70);
+                   (uint8_t *)els_iocb,
+                   sizeof(*els_iocb));
        } else {
                els_iocb->control_flags = 1 << 13;
                els_iocb->tx_byte_count =
@@ -2688,6 +2701,11 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
                els_iocb->rx_byte_count = 0;
                els_iocb->rx_address = 0;
                els_iocb->rx_len = 0;
+               ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3076,
+                      "LOGO ELS IOCB:");
+               ql_dump_buffer(ql_log_info, vha, 0x010b,
+                              els_iocb,
+                              sizeof(*els_iocb));
        }
 
        sp->vha->qla_stats.control_requests++;
@@ -2934,7 +2952,8 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
 
        ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
        ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109,
-           (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70);
+           (uint8_t *)elsio->u.els_plogi.els_plogi_pyld,
+           sizeof(*elsio->u.els_plogi.els_plogi_pyld));
 
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
index 1b8f297..7b8a6bf 100644 (file)
@@ -1061,8 +1061,6 @@ global_port_update:
                        ql_dbg(ql_dbg_async, vha, 0x5011,
                            "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n",
                            mb[1], mb[2], mb[3]);
-
-                       qlt_async_event(mb[0], vha, mb);
                        break;
                }
 
@@ -1079,8 +1077,6 @@ global_port_update:
                set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
                set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
                set_bit(VP_CONFIG_OK, &vha->vp_flags);
-
-               qlt_async_event(mb[0], vha, mb);
                break;
 
        case MBA_RSCN_UPDATE:           /* State Change Registration */
@@ -3650,7 +3646,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
 skip_msix:
 
        ql_log(ql_log_info, vha, 0x0037,
-           "Falling back-to MSI mode -%d.\n", ret);
+           "Falling back-to MSI mode -- ret=%d.\n", ret);
 
        if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
            !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) &&
@@ -3658,13 +3654,13 @@ skip_msix:
                goto skip_msi;
 
        ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI);
-       if (!ret) {
+       if (ret > 0) {
                ql_dbg(ql_dbg_init, vha, 0x0038,
                    "MSI: Enabled.\n");
                ha->flags.msi_enabled = 1;
        } else
                ql_log(ql_log_warn, vha, 0x0039,
-                   "Falling back-to INTa mode -- %d.\n", ret);
+                   "Falling back-to INTa mode -- ret=%d.\n", ret);
 skip_msi:
 
        /* Skip INTx on ISP82xx. */
index 0cf94f0..b7c1108 100644 (file)
@@ -3921,6 +3921,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                                        vha->d_id.b24 = 0;
                                        vha->d_id.b.al_pa = 1;
                                        ha->flags.n2n_bigger = 1;
+                                       ha->flags.n2n_ae = 0;
 
                                        id.b.al_pa = 2;
                                        ql_dbg(ql_dbg_async, vha, 0x5075,
@@ -3931,6 +3932,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                                            "Format 1: Remote login - Waiting for WWPN %8phC.\n",
                                            rptid_entry->u.f1.port_name);
                                        ha->flags.n2n_bigger = 0;
+                                       ha->flags.n2n_ae = 1;
                                }
                                qla24xx_post_newsess_work(vha, &id,
                                    rptid_entry->u.f1.port_name,
@@ -3942,7 +3944,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                        /* if our portname is higher then initiate N2N login */
 
                        set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
-                       ha->flags.n2n_ae = 1;
                        return;
                        break;
                case TOPO_FL:
index 941aa53..bfcd02f 100644 (file)
@@ -610,6 +610,7 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
 }
 
 static struct nvme_fc_port_template qla_nvme_fc_transport = {
+       .module = THIS_MODULE,
        .localport_delete = qla_nvme_localport_delete,
        .remoteport_delete = qla_nvme_remoteport_delete,
        .create_queue   = qla_nvme_alloc_queue,
index f2d5115..bbe9035 100644 (file)
@@ -847,15 +847,15 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
                                ha->flt_region_img_status_pri = start;
                        break;
                case FLT_REG_IMG_SEC_27XX:
-                       if (IS_QLA27XX(ha) && !IS_QLA28XX(ha))
+                       if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
                                ha->flt_region_img_status_sec = start;
                        break;
                case FLT_REG_FW_SEC_27XX:
-                       if (IS_QLA27XX(ha) && !IS_QLA28XX(ha))
+                       if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
                                ha->flt_region_fw_sec = start;
                        break;
                case FLT_REG_BOOTLOAD_SEC_27XX:
-                       if (IS_QLA27XX(ha) && !IS_QLA28XX(ha))
+                       if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
                                ha->flt_region_boot_sec = start;
                        break;
                case FLT_REG_AUX_IMG_PRI_28XX:
@@ -2725,8 +2725,11 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
                ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff,
                    "Region %x is secure\n", region.code);
 
-               if (region.code == FLT_REG_FW ||
-                   region.code == FLT_REG_FW_SEC_27XX) {
+               switch (region.code) {
+               case FLT_REG_FW:
+               case FLT_REG_FW_SEC_27XX:
+               case FLT_REG_MPI_PRI_28XX:
+               case FLT_REG_MPI_SEC_28XX:
                        fw_array = dwptr;
 
                        /* 1st fw array */
@@ -2757,9 +2760,23 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
                                buf_size_without_sfub += risc_size;
                                fw_array += risc_size;
                        }
-               } else {
-                       ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff,
-                           "Secure region %x not supported\n",
+                       break;
+
+               case FLT_REG_PEP_PRI_28XX:
+               case FLT_REG_PEP_SEC_28XX:
+                       fw_array = dwptr;
+
+                       /* 1st fw array */
+                       risc_size = be32_to_cpu(fw_array[3]);
+                       risc_attr = be32_to_cpu(fw_array[9]);
+
+                       buf_size_without_sfub = risc_size;
+                       fw_array += risc_size;
+                       break;
+
+               default:
+                       ql_log(ql_log_warn + ql_dbg_verbose, vha,
+                           0xffff, "Secure region %x not supported\n",
                            region.code);
                        rval = QLA_COMMAND_ERROR;
                        goto done;
@@ -2880,7 +2897,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
                            "Sending Secure Flash MB Cmd\n");
                        rval = qla28xx_secure_flash_update(vha, 0, region.code,
                                buf_size_without_sfub, sfub_dma,
-                               sizeof(struct secure_flash_update_block));
+                               sizeof(struct secure_flash_update_block) >> 2);
                        if (rval != QLA_SUCCESS) {
                                ql_log(ql_log_warn, vha, 0xffff,
                                    "Secure Flash MB Cmd failed %x.", rval);
index 51b275a..68c1414 100644 (file)
@@ -1104,6 +1104,7 @@ void qlt_free_session_done(struct work_struct *work)
                }
        }
 
+       sess->explicit_logout = 0;
        spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        sess->free_pending = 0;
 
@@ -1160,7 +1161,6 @@ void qlt_unreg_sess(struct fc_port *sess)
        sess->last_rscn_gen = sess->rscn_gen;
        sess->last_login_gen = sess->login_gen;
 
-       INIT_WORK(&sess->free_work, qlt_free_session_done);
        queue_work(sess->vha->hw->wq, &sess->free_work);
 }
 EXPORT_SYMBOL(qlt_unreg_sess);
@@ -1265,7 +1265,6 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
            "Scheduling sess %p for deletion %8phC\n",
            sess, sess->port_name);
 
-       INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn);
        WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work));
 }
 
@@ -4804,6 +4803,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
 
        switch (sess->disc_state) {
        case DSC_DELETED:
+       case DSC_LOGIN_PEND:
                qlt_plogi_ack_unref(vha, pla);
                break;
 
index 042a243..abe7f79 100644 (file)
@@ -246,6 +246,8 @@ static void tcm_qla2xxx_complete_mcmd(struct work_struct *work)
  */
 static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
 {
+       if (!mcmd)
+               return;
        INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd);
        queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work);
 }
@@ -348,6 +350,7 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess)
        target_sess_cmd_list_set_waiting(se_sess);
        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
+       sess->explicit_logout = 1;
        tcm_qla2xxx_put_sess(sess);
 }
 
index 8c674ec..2323432 100644 (file)
@@ -4275,7 +4275,6 @@ static int qla4xxx_mem_alloc(struct scsi_qla_host *ha)
        return QLA_SUCCESS;
 
 mem_alloc_error_exit:
-       qla4xxx_mem_free(ha);
        return QLA_ERROR;
 }
 
index 417b868..ed8d970 100644 (file)
@@ -24,6 +24,8 @@
 
 #define ISCSI_TRANSPORT_VERSION "2.0-870"
 
+#define ISCSI_SEND_MAX_ALLOWED  10
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/iscsi.h>
 
@@ -3682,6 +3684,7 @@ iscsi_if_rx(struct sk_buff *skb)
                struct nlmsghdr *nlh;
                struct iscsi_uevent *ev;
                uint32_t group;
+               int retries = ISCSI_SEND_MAX_ALLOWED;
 
                nlh = nlmsg_hdr(skb);
                if (nlh->nlmsg_len < sizeof(*nlh) + sizeof(*ev) ||
@@ -3712,6 +3715,10 @@ iscsi_if_rx(struct sk_buff *skb)
                                break;
                        err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
                                                  ev, sizeof(*ev));
+                       if (err == -EAGAIN && --retries < 0) {
+                               printk(KERN_WARNING "Send reply failed, error %d\n", err);
+                               break;
+                       }
                } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
                skb_pull(skb, rlen);
        }
index ef138c5..182fd25 100644 (file)
@@ -1391,9 +1391,6 @@ static void sas_expander_release(struct device *dev)
        struct sas_rphy *rphy = dev_to_rphy(dev);
        struct sas_expander_device *edev = rphy_to_expander_device(rphy);
 
-       if (rphy->q)
-               blk_cleanup_queue(rphy->q);
-
        put_device(dev->parent);
        kfree(edev);
 }
@@ -1403,9 +1400,6 @@ static void sas_end_device_release(struct device *dev)
        struct sas_rphy *rphy = dev_to_rphy(dev);
        struct sas_end_device *edev = rphy_to_end_device(rphy);
 
-       if (rphy->q)
-               blk_cleanup_queue(rphy->q);
-
        put_device(dev->parent);
        kfree(edev);
 }
@@ -1634,8 +1628,7 @@ sas_rphy_remove(struct sas_rphy *rphy)
        }
 
        sas_rphy_unlink(rphy);
-       if (rphy->q)
-               bsg_unregister_queue(rphy->q);
+       bsg_remove_queue(rphy->q);
        transport_remove_device(dev);
        device_del(dev);
 }
index 7dc1782..cea6259 100644 (file)
@@ -122,8 +122,6 @@ static void sd_eh_reset(struct scsi_cmnd *);
 static int sd_eh_action(struct scsi_cmnd *, int);
 static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
 static void scsi_disk_release(struct device *cdev);
-static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
-static void sd_print_result(const struct scsi_disk *, const char *, int);
 
 static DEFINE_IDA(sd_index_ida);
 
@@ -3726,15 +3724,13 @@ static void __exit exit_sd(void)
 module_init(init_sd);
 module_exit(exit_sd);
 
-static void sd_print_sense_hdr(struct scsi_disk *sdkp,
-                              struct scsi_sense_hdr *sshdr)
+void sd_print_sense_hdr(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
 {
        scsi_print_sense_hdr(sdkp->device,
                             sdkp->disk ? sdkp->disk->disk_name : NULL, sshdr);
 }
 
-static void sd_print_result(const struct scsi_disk *sdkp, const char *msg,
-                           int result)
+void sd_print_result(const struct scsi_disk *sdkp, const char *msg, int result)
 {
        const char *hb_string = scsi_hostbyte_string(result);
        const char *db_string = scsi_driverbyte_string(result);
@@ -3749,4 +3745,3 @@ static void sd_print_result(const struct scsi_disk *sdkp, const char *msg,
                          "%s: Result: hostbyte=0x%02x driverbyte=0x%02x\n",
                          msg, host_byte(result), driver_byte(result));
 }
-
index 42fd3f0..50fff0b 100644 (file)
@@ -241,4 +241,7 @@ static inline void sd_zbc_complete(struct scsi_cmnd *cmd,
 
 #endif /* CONFIG_BLK_DEV_ZONED */
 
+void sd_print_sense_hdr(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr);
+void sd_print_result(const struct scsi_disk *sdkp, const char *msg, int result);
+
 #endif /* _SCSI_DISK_H */
index 0e5ede4..e0bd4cf 100644 (file)
@@ -80,9 +80,11 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
                                  timeout, SD_MAX_RETRIES, NULL);
        if (result) {
                sd_printk(KERN_ERR, sdkp,
-                         "REPORT ZONES lba %llu failed with %d/%d\n",
-                         (unsigned long long)lba,
-                         host_byte(result), driver_byte(result));
+                         "REPORT ZONES start lba %llu failed\n", lba);
+               sd_print_result(sdkp, "REPORT ZONES", result);
+               if (driver_byte(result) == DRIVER_SENSE &&
+                   scsi_sense_valid(&sshdr))
+                       sd_print_sense_hdr(sdkp, &sshdr);
                return -EIO;
        }
 
@@ -412,8 +414,6 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)
                goto err;
 
        /* The drive satisfies the kernel restrictions: set it up */
-       blk_queue_chunk_sectors(sdkp->disk->queue,
-                       logical_to_sectors(sdkp->device, zone_blocks));
        blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, sdkp->disk->queue);
        blk_queue_required_elevator_features(sdkp->disk->queue,
                                             ELEVATOR_F_ZBD_SEQ_WRITE);
index 7b7ef3a..412ac56 100644 (file)
@@ -8689,11 +8689,11 @@ static void __attribute__((unused)) verify_structures(void)
        BUILD_BUG_ON(offsetof(struct pqi_general_admin_request,
                data.delete_operational_queue.queue_id) != 12);
        BUILD_BUG_ON(sizeof(struct pqi_general_admin_request) != 64);
-       BUILD_BUG_ON(FIELD_SIZEOF(struct pqi_general_admin_request,
+       BUILD_BUG_ON(sizeof_field(struct pqi_general_admin_request,
                data.create_operational_iq) != 64 - 11);
-       BUILD_BUG_ON(FIELD_SIZEOF(struct pqi_general_admin_request,
+       BUILD_BUG_ON(sizeof_field(struct pqi_general_admin_request,
                data.create_operational_oq) != 64 - 11);
-       BUILD_BUG_ON(FIELD_SIZEOF(struct pqi_general_admin_request,
+       BUILD_BUG_ON(sizeof_field(struct pqi_general_admin_request,
                data.delete_operational_queue) != 64 - 11);
 
        BUILD_BUG_ON(offsetof(struct pqi_general_admin_response,
index b2af04c..6feeb0f 100644 (file)
@@ -99,6 +99,12 @@ static int cdns_ufs_link_startup_notify(struct ufs_hba *hba,
         */
        ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0);
 
+       /*
+        * Disabling Autohibern8 feature in cadence UFS
+        * to mask unexpected interrupt trigger.
+        */
+       hba->ahit = 0;
+
        return 0;
 }
 
index baeecee..53dd876 100644 (file)
@@ -203,7 +203,7 @@ int ufs_bsg_probe(struct ufs_hba *hba)
        bsg_dev->parent = get_device(parent);
        bsg_dev->release = ufs_bsg_node_release;
 
-       dev_set_name(bsg_dev, "ufs-bsg");
+       dev_set_name(bsg_dev, "ufs-bsg%u", shost->host_no);
 
        ret = device_add(bsg_dev);
        if (ret)
index 6d0d04f..01fc0d2 100644 (file)
@@ -40,6 +40,7 @@ static const struct meson_gx_soc_id {
        { "G12A", 0x28 },
        { "G12B", 0x29 },
        { "SM1", 0x2b },
+       { "A1", 0x2c },
 };
 
 static const struct meson_gx_package_id {
@@ -68,6 +69,8 @@ static const struct meson_gx_package_id {
        { "S922X", 0x29, 0x40, 0xf0 },
        { "A311D", 0x29, 0x10, 0xf0 },
        { "S905X3", 0x2b, 0x5, 0xf },
+       { "S905D3", 0x2b, 0xb0, 0xf0 },
+       { "A113L", 0x2c, 0x0, 0xf8 },
 };
 
 static inline unsigned int socinfo_to_major(u32 socinfo)
index 48f7ac2..f3d8d53 100644 (file)
@@ -97,13 +97,13 @@ static ssize_t snoop_file_read(struct file *file, char __user *buffer,
        return ret ? ret : copied;
 }
 
-static unsigned int snoop_file_poll(struct file *file,
+static __poll_t snoop_file_poll(struct file *file,
                                    struct poll_table_struct *pt)
 {
        struct aspeed_lpc_snoop_channel *chan = snoop_file_to_chan(file);
 
        poll_wait(file, &chan->wq, pt);
-       return !kfifo_is_empty(&chan->fifo) ? POLLIN : 0;
+       return !kfifo_is_empty(&chan->fifo) ? EPOLLIN : 0;
 }
 
 static const struct file_operations snoop_fops = {
index 0552813..50caf6d 100644 (file)
@@ -5,3 +5,14 @@ config AT91_SOC_ID
        default ARCH_AT91
        help
          Include support for the SoC bus on the Atmel ARM SoCs.
+
+config AT91_SOC_SFR
+       tristate "Special Function Registers support"
+       depends on ARCH_AT91 || COMPILE_TEST
+       help
+         This is a driver for the Special Function Registers available on
+         Atmel SAMA5Dx SoCs, providing access to specific aspects of the
+         integrated memory, bridge implementations, processor etc.
+
+         This driver can also be built as a module. If so, the module
+         will be called sfr.
index 7ca355d..d849a89 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_AT91_SOC_ID) += soc.o
+obj-$(CONFIG_AT91_SOC_SFR) += sfr.o
diff --git a/drivers/soc/atmel/sfr.c b/drivers/soc/atmel/sfr.c
new file mode 100644 (file)
index 0000000..0525eef
--- /dev/null
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * sfr.c - driver for special function registers
+ *
+ * Copyright (C) 2019 Bootlin.
+ *
+ */
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/random.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define SFR_SN0                0x4c
+#define SFR_SN_SIZE    8
+
+struct atmel_sfr_priv {
+       struct regmap                   *regmap;
+};
+
+static int atmel_sfr_read(void *context, unsigned int offset,
+                         void *buf, size_t bytes)
+{
+       struct atmel_sfr_priv *priv = context;
+
+       return regmap_bulk_read(priv->regmap, SFR_SN0 + offset,
+                               buf, bytes / 4);
+}
+
+static struct nvmem_config atmel_sfr_nvmem_config = {
+       .name = "atmel-sfr",
+       .read_only = true,
+       .word_size = 4,
+       .stride = 4,
+       .size = SFR_SN_SIZE,
+       .reg_read = atmel_sfr_read,
+};
+
+static int atmel_sfr_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct nvmem_device *nvmem;
+       struct atmel_sfr_priv *priv;
+       u8 sn[SFR_SN_SIZE];
+       int ret;
+
+       priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->regmap = syscon_node_to_regmap(np);
+       if (IS_ERR(priv->regmap)) {
+               dev_err(dev, "cannot get parent's regmap\n");
+               return PTR_ERR(priv->regmap);
+       }
+
+       atmel_sfr_nvmem_config.dev = dev;
+       atmel_sfr_nvmem_config.priv = priv;
+
+       nvmem = devm_nvmem_register(dev, &atmel_sfr_nvmem_config);
+       if (IS_ERR(nvmem)) {
+               dev_err(dev, "error registering nvmem config\n");
+               return PTR_ERR(nvmem);
+       }
+
+       ret = atmel_sfr_read(priv, 0, sn, SFR_SN_SIZE);
+       if (ret == 0)
+               add_device_randomness(sn, SFR_SN_SIZE);
+
+       return ret;
+}
+
+static const struct of_device_id atmel_sfr_dt_ids[] = {
+       {
+               .compatible = "atmel,sama5d2-sfr",
+       }, {
+               .compatible = "atmel,sama5d4-sfr",
+       }, {
+               /* sentinel */
+       },
+};
+MODULE_DEVICE_TABLE(of, atmel_sfr_dt_ids);
+
+static struct platform_driver atmel_sfr_driver = {
+       .probe = atmel_sfr_probe,
+       .driver = {
+               .name = "atmel-sfr",
+               .of_match_table = atmel_sfr_dt_ids,
+       },
+};
+module_platform_driver(atmel_sfr_driver);
+
+MODULE_AUTHOR("Kamel Bouhara <kamel.bouhara@bootlin.com>");
+MODULE_DESCRIPTION("Atmel SFR SN driver for SAMA5D2/4 SoC family");
+MODULE_LICENSE("GPL v2");
index f9ad8ad..4df32bc 100644 (file)
@@ -40,4 +40,14 @@ config DPAA2_CONSOLE
          /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console,
          which can be used to dump the Management Complex and AIOP
          firmware logs.
+
+config FSL_RCPM
+       bool "Freescale RCPM support"
+       depends on PM_SLEEP && (ARM || ARM64)
+       help
+         The NXP QorIQ Processors based on ARM Core have RCPM module
+         (Run Control and Power Management), which performs all device-level
+         tasks associated with power management, such as wakeup source control.
+         Note that currently this driver will not support PowerPC based
+         QorIQ processor.
 endmenu
index 71dee8d..906f1cd 100644 (file)
@@ -6,6 +6,7 @@
 obj-$(CONFIG_FSL_DPAA)                 += qbman/
 obj-$(CONFIG_QUICC_ENGINE)             += qe/
 obj-$(CONFIG_CPM)                      += qe/
+obj-$(CONFIG_FSL_RCPM)                 += rcpm.o
 obj-$(CONFIG_FSL_GUTS)                 += guts.o
 obj-$(CONFIG_FSL_MC_DPIO)              += dpio/
 obj-$(CONFIG_DPAA2_CONSOLE)            += dpaa2-console.o
diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c
new file mode 100644 (file)
index 0000000..a093dbe
--- /dev/null
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// rcpm.c - Freescale QorIQ RCPM driver
+//
+// Copyright 2019 NXP
+//
+// Author: Ran Wang <ran.wang_1@nxp.com>
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/kernel.h>
+
+#define RCPM_WAKEUP_CELL_MAX_SIZE      7
+
+struct rcpm {
+       unsigned int    wakeup_cells;
+       void __iomem    *ippdexpcr_base;
+       bool            little_endian;
+};
+
+/**
+ * rcpm_pm_prepare - performs device-level tasks associated with power
+ * management, such as programming related to the wakeup source control.
+ * @dev: Device to handle.
+ *
+ */
+static int rcpm_pm_prepare(struct device *dev)
+{
+       int i, ret, idx;
+       void __iomem *base;
+       struct wakeup_source    *ws;
+       struct rcpm             *rcpm;
+       struct device_node      *np = dev->of_node;
+       u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1];
+       u32 setting[RCPM_WAKEUP_CELL_MAX_SIZE] = {0};
+
+       rcpm = dev_get_drvdata(dev);
+       if (!rcpm)
+               return -EINVAL;
+
+       base = rcpm->ippdexpcr_base;
+       idx = wakeup_sources_read_lock();
+
+       /* Begin with first registered wakeup source */
+       for_each_wakeup_source(ws) {
+
+               /* skip object which is not attached to device */
+               if (!ws->dev || !ws->dev->parent)
+                       continue;
+
+               ret = device_property_read_u32_array(ws->dev->parent,
+                               "fsl,rcpm-wakeup", value,
+                               rcpm->wakeup_cells + 1);
+
+               /*  Wakeup source should refer to current rcpm device */
+               if (ret || (np->phandle != value[0]))
+                       continue;
+
+               /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines the
+                * number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup"
+                * of wakeup source IP contains an integer array: <phandle to
+                * RCPM node, IPPDEXPCR0 setting, IPPDEXPCR1 setting,
+                * IPPDEXPCR2 setting, etc>.
+                *
+                * So we will go thought them to collect setting data.
+                */
+               for (i = 0; i < rcpm->wakeup_cells; i++)
+                       setting[i] |= value[i + 1];
+       }
+
+       wakeup_sources_read_unlock(idx);
+
+       /* Program all IPPDEXPCRn once */
+       for (i = 0; i < rcpm->wakeup_cells; i++) {
+               u32 tmp = setting[i];
+               void __iomem *address = base + i * 4;
+
+               if (!tmp)
+                       continue;
+
+               /* We can only OR related bits */
+               if (rcpm->little_endian) {
+                       tmp |= ioread32(address);
+                       iowrite32(tmp, address);
+               } else {
+                       tmp |= ioread32be(address);
+                       iowrite32be(tmp, address);
+               }
+       }
+
+       return 0;
+}
+
+static const struct dev_pm_ops rcpm_pm_ops = {
+       .prepare =  rcpm_pm_prepare,
+};
+
+static int rcpm_probe(struct platform_device *pdev)
+{
+       struct device   *dev = &pdev->dev;
+       struct resource *r;
+       struct rcpm     *rcpm;
+       int ret;
+
+       rcpm = devm_kzalloc(dev, sizeof(*rcpm), GFP_KERNEL);
+       if (!rcpm)
+               return -ENOMEM;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r)
+               return -ENODEV;
+
+       rcpm->ippdexpcr_base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(rcpm->ippdexpcr_base)) {
+               ret =  PTR_ERR(rcpm->ippdexpcr_base);
+               return ret;
+       }
+
+       rcpm->little_endian = device_property_read_bool(
+                       &pdev->dev, "little-endian");
+
+       ret = device_property_read_u32(&pdev->dev,
+                       "#fsl,rcpm-wakeup-cells", &rcpm->wakeup_cells);
+       if (ret)
+               return ret;
+
+       dev_set_drvdata(&pdev->dev, rcpm);
+
+       return 0;
+}
+
+static const struct of_device_id rcpm_of_match[] = {
+       { .compatible = "fsl,qoriq-rcpm-2.1+", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, rcpm_of_match);
+
+static struct platform_driver rcpm_driver = {
+       .driver = {
+               .name = "rcpm",
+               .of_match_table = rcpm_of_match,
+               .pm     = &rcpm_pm_ops,
+       },
+       .probe = rcpm_probe,
+};
+
+module_platform_driver(rcpm_driver);
index c68882e..fb70b8a 100644 (file)
@@ -33,12 +33,10 @@ struct imx_sc_msg_misc_get_soc_uid {
        u32 uid_high;
 } __packed;
 
-static ssize_t soc_uid_show(struct device *dev,
-                           struct device_attribute *attr, char *buf)
+static int imx_scu_soc_uid(u64 *soc_uid)
 {
        struct imx_sc_msg_misc_get_soc_uid msg;
        struct imx_sc_rpc_msg *hdr = &msg.hdr;
-       u64 soc_uid;
        int ret;
 
        hdr->ver = IMX_SC_RPC_VERSION;
@@ -52,15 +50,13 @@ static ssize_t soc_uid_show(struct device *dev,
                return ret;
        }
 
-       soc_uid = msg.uid_high;
-       soc_uid <<= 32;
-       soc_uid |= msg.uid_low;
+       *soc_uid = msg.uid_high;
+       *soc_uid <<= 32;
+       *soc_uid |= msg.uid_low;
 
-       return sprintf(buf, "%016llX\n", soc_uid);
+       return 0;
 }
 
-static DEVICE_ATTR_RO(soc_uid);
-
 static int imx_scu_soc_id(void)
 {
        struct imx_sc_msg_misc_get_soc_id msg;
@@ -89,6 +85,7 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
        struct soc_device_attribute *soc_dev_attr;
        struct soc_device *soc_dev;
        int id, ret;
+       u64 uid = 0;
        u32 val;
 
        ret = imx_scu_get_handle(&soc_ipc_handle);
@@ -112,6 +109,10 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
        if (id < 0)
                return -EINVAL;
 
+       ret = imx_scu_soc_uid(&uid);
+       if (ret < 0)
+               return -EINVAL;
+
        /* format soc_id value passed from SCU firmware */
        val = id & 0x1f;
        soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x", val);
@@ -130,19 +131,22 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
                goto free_soc_id;
        }
 
+       soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", uid);
+       if (!soc_dev_attr->serial_number) {
+               ret = -ENOMEM;
+               goto free_revision;
+       }
+
        soc_dev = soc_device_register(soc_dev_attr);
        if (IS_ERR(soc_dev)) {
                ret = PTR_ERR(soc_dev);
-               goto free_revision;
+               goto free_serial_number;
        }
 
-       ret = device_create_file(soc_device_to_device(soc_dev),
-                                &dev_attr_soc_uid);
-       if (ret)
-               goto free_revision;
-
        return 0;
 
+free_serial_number:
+       kfree(soc_dev_attr->serial_number);
 free_revision:
        kfree(soc_dev_attr->revision);
 free_soc_id:
index b983157..d84ed73 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
 #include <linux/platform_device.h>
+#include <linux/arm-smccc.h>
 #include <linux/of.h>
 
 #define REV_B1                         0x21
@@ -16,6 +17,8 @@
 #define IMX8MQ_SW_INFO_B1              0x40
 #define IMX8MQ_SW_MAGIC_B1             0xff0055aa
 
+#define IMX_SIP_GET_SOC_INFO           0xc2000006
+
 #define OCOTP_UID_LOW                  0x410
 #define OCOTP_UID_HIGH                 0x420
 
@@ -29,13 +32,21 @@ struct imx8_soc_data {
 
 static u64 soc_uid;
 
-static ssize_t soc_uid_show(struct device *dev,
-                           struct device_attribute *attr, char *buf)
+#ifdef CONFIG_HAVE_ARM_SMCCC
+static u32 imx8mq_soc_revision_from_atf(void)
 {
-       return sprintf(buf, "%016llX\n", soc_uid);
-}
+       struct arm_smccc_res res;
 
-static DEVICE_ATTR_RO(soc_uid);
+       arm_smccc_smc(IMX_SIP_GET_SOC_INFO, 0, 0, 0, 0, 0, 0, 0, &res);
+
+       if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+               return 0;
+       else
+               return res.a0 & 0xff;
+}
+#else
+static inline u32 imx8mq_soc_revision_from_atf(void) { return 0; };
+#endif
 
 static u32 __init imx8mq_soc_revision(void)
 {
@@ -51,9 +62,16 @@ static u32 __init imx8mq_soc_revision(void)
        ocotp_base = of_iomap(np, 0);
        WARN_ON(!ocotp_base);
 
-       magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1);
-       if (magic == IMX8MQ_SW_MAGIC_B1)
-               rev = REV_B1;
+       /*
+        * SOC revision on older imx8mq is not available in fuses so query
+        * the value from ATF instead.
+        */
+       rev = imx8mq_soc_revision_from_atf();
+       if (!rev) {
+               magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1);
+               if (magic == IMX8MQ_SW_MAGIC_B1)
+                       rev = REV_B1;
+       }
 
        soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
        soc_uid <<= 32;
@@ -174,22 +192,25 @@ static int __init imx8_soc_init(void)
                goto free_soc;
        }
 
+       soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", soc_uid);
+       if (!soc_dev_attr->serial_number) {
+               ret = -ENOMEM;
+               goto free_rev;
+       }
+
        soc_dev = soc_device_register(soc_dev_attr);
        if (IS_ERR(soc_dev)) {
                ret = PTR_ERR(soc_dev);
-               goto free_rev;
+               goto free_serial_number;
        }
 
-       ret = device_create_file(soc_device_to_device(soc_dev),
-                                &dev_attr_soc_uid);
-       if (ret)
-               goto free_rev;
-
        if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
                platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
 
        return 0;
 
+free_serial_number:
+       kfree(soc_dev_attr->serial_number);
 free_rev:
        if (strcmp(soc_dev_attr->revision, "unknown"))
                kfree(soc_dev_attr->revision);
index 7aa0517..3c82de5 100644 (file)
@@ -155,7 +155,7 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
                err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
                offset_mask |= CMDQ_WRITE_ENABLE_MASK;
        }
-       err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
+       err |= cmdq_pkt_write(pkt, subsys, offset_mask, value);
 
        return err;
 }
index 503222d..f669d37 100644 (file)
@@ -21,7 +21,7 @@
 #include <dt-bindings/power/mt8173-power.h>
 
 #define MTK_POLL_DELAY_US   10
-#define MTK_POLL_TIMEOUT    (jiffies_to_usecs(HZ))
+#define MTK_POLL_TIMEOUT    USEC_PER_SEC
 
 #define MTK_SCPD_ACTIVE_WAKEUP         BIT(0)
 #define MTK_SCPD_FWAIT_SRAM            BIT(1)
@@ -108,6 +108,17 @@ static const char * const clk_names[] = {
 
 #define MAX_CLKS       3
 
+/**
+ * struct scp_domain_data - scp domain data for power on/off flow
+ * @name: The domain name.
+ * @sta_mask: The mask for power on/off status bit.
+ * @ctl_offs: The offset for main power control register.
+ * @sram_pdn_bits: The mask for sram power control bits.
+ * @sram_pdn_ack_bits: The mask for sram power control acked bits.
+ * @bus_prot_mask: The mask for single step bus protection.
+ * @clk_id: The basic clocks required by this power domain.
+ * @caps: The flag for active wake-up action.
+ */
 struct scp_domain_data {
        const char *name;
        u32 sta_mask;
@@ -180,32 +191,132 @@ static int scpsys_domain_is_on(struct scp_domain *scpd)
        return -EINVAL;
 }
 
+static int scpsys_regulator_enable(struct scp_domain *scpd)
+{
+       if (!scpd->supply)
+               return 0;
+
+       return regulator_enable(scpd->supply);
+}
+
+static int scpsys_regulator_disable(struct scp_domain *scpd)
+{
+       if (!scpd->supply)
+               return 0;
+
+       return regulator_disable(scpd->supply);
+}
+
+static void scpsys_clk_disable(struct clk *clk[], int max_num)
+{
+       int i;
+
+       for (i = max_num - 1; i >= 0; i--)
+               clk_disable_unprepare(clk[i]);
+}
+
+static int scpsys_clk_enable(struct clk *clk[], int max_num)
+{
+       int i, ret = 0;
+
+       for (i = 0; i < max_num && clk[i]; i++) {
+               ret = clk_prepare_enable(clk[i]);
+               if (ret) {
+                       scpsys_clk_disable(clk, i);
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
+{
+       u32 val;
+       u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
+       int tmp;
+
+       val = readl(ctl_addr);
+       val &= ~scpd->data->sram_pdn_bits;
+       writel(val, ctl_addr);
+
+       /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
+       if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
+               /*
+                * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
+                * MT7622_POWER_DOMAIN_WB and thus just a trivial setup
+                * is applied here.
+                */
+               usleep_range(12000, 12100);
+       } else {
+               /* Either wait until SRAM_PDN_ACK all 1 or 0 */
+               int ret = readl_poll_timeout(ctl_addr, tmp,
+                               (tmp & pdn_ack) == 0,
+                               MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
+{
+       u32 val;
+       u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
+       int tmp;
+
+       val = readl(ctl_addr);
+       val |= scpd->data->sram_pdn_bits;
+       writel(val, ctl_addr);
+
+       /* Either wait until SRAM_PDN_ACK all 1 or 0 */
+       return readl_poll_timeout(ctl_addr, tmp,
+                       (tmp & pdn_ack) == pdn_ack,
+                       MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+}
+
+static int scpsys_bus_protect_enable(struct scp_domain *scpd)
+{
+       struct scp *scp = scpd->scp;
+
+       if (!scpd->data->bus_prot_mask)
+               return 0;
+
+       return mtk_infracfg_set_bus_protection(scp->infracfg,
+                       scpd->data->bus_prot_mask,
+                       scp->bus_prot_reg_update);
+}
+
+static int scpsys_bus_protect_disable(struct scp_domain *scpd)
+{
+       struct scp *scp = scpd->scp;
+
+       if (!scpd->data->bus_prot_mask)
+               return 0;
+
+       return mtk_infracfg_clear_bus_protection(scp->infracfg,
+                       scpd->data->bus_prot_mask,
+                       scp->bus_prot_reg_update);
+}
+
 static int scpsys_power_on(struct generic_pm_domain *genpd)
 {
        struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
        struct scp *scp = scpd->scp;
        void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
-       u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
        u32 val;
        int ret, tmp;
-       int i;
 
-       if (scpd->supply) {
-               ret = regulator_enable(scpd->supply);
-               if (ret)
-                       return ret;
-       }
-
-       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]);
+       ret = scpsys_regulator_enable(scpd);
+       if (ret < 0)
+               return ret;
 
-                       goto err_clk;
-               }
-       }
+       ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
+       if (ret)
+               goto err_clk;
 
+       /* subsys power on */
        val = readl(ctl_addr);
        val |= PWR_ON_BIT;
        writel(val, ctl_addr);
@@ -227,43 +338,20 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        val |= PWR_RST_B_BIT;
        writel(val, ctl_addr);
 
-       val &= ~scpd->data->sram_pdn_bits;
-       writel(val, ctl_addr);
-
-       /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
-       if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
-               /*
-                * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
-                * MT7622_POWER_DOMAIN_WB and thus just a trivial setup is
-                * applied here.
-                */
-               usleep_range(12000, 12100);
-
-       } else {
-               ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
-                                        MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
-               if (ret < 0)
-                       goto err_pwr_ack;
-       }
+       ret = scpsys_sram_enable(scpd, ctl_addr);
+       if (ret < 0)
+               goto err_pwr_ack;
 
-       if (scpd->data->bus_prot_mask) {
-               ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
-                               scpd->data->bus_prot_mask,
-                               scp->bus_prot_reg_update);
-               if (ret)
-                       goto err_pwr_ack;
-       }
+       ret = scpsys_bus_protect_disable(scpd);
+       if (ret < 0)
+               goto err_pwr_ack;
 
        return 0;
 
 err_pwr_ack:
-       for (i = MAX_CLKS - 1; i >= 0; i--) {
-               if (scpd->clk[i])
-                       clk_disable_unprepare(scpd->clk[i]);
-       }
+       scpsys_clk_disable(scpd->clk, MAX_CLKS);
 err_clk:
-       if (scpd->supply)
-               regulator_disable(scpd->supply);
+       scpsys_regulator_disable(scpd);
 
        dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
 
@@ -275,29 +363,19 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
        struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
        struct scp *scp = scpd->scp;
        void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
-       u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
        u32 val;
        int ret, tmp;
-       int i;
-
-       if (scpd->data->bus_prot_mask) {
-               ret = mtk_infracfg_set_bus_protection(scp->infracfg,
-                               scpd->data->bus_prot_mask,
-                               scp->bus_prot_reg_update);
-               if (ret)
-                       goto out;
-       }
 
-       val = readl(ctl_addr);
-       val |= scpd->data->sram_pdn_bits;
-       writel(val, ctl_addr);
+       ret = scpsys_bus_protect_enable(scpd);
+       if (ret < 0)
+               goto out;
 
-       /* wait until SRAM_PDN_ACK all 1 */
-       ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
-                                MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+       ret = scpsys_sram_disable(scpd, ctl_addr);
        if (ret < 0)
                goto out;
 
+       /* subsys power off */
+       val = readl(ctl_addr);
        val |= PWR_ISO_BIT;
        writel(val, ctl_addr);
 
@@ -319,11 +397,11 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
        if (ret < 0)
                goto out;
 
-       for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
-               clk_disable_unprepare(scpd->clk[i]);
+       scpsys_clk_disable(scpd->clk, MAX_CLKS);
 
-       if (scpd->supply)
-               regulator_disable(scpd->supply);
+       ret = scpsys_regulator_disable(scpd);
+       if (ret < 0)
+               goto out;
 
        return 0;
 
index 661e47a..79d8265 100644 (file)
@@ -58,22 +58,24 @@ config QCOM_LLCC
        depends on ARCH_QCOM || COMPILE_TEST
        help
          Qualcomm Technologies, Inc. platform specific
-         Last Level Cache Controller(LLCC) driver. This provides interfaces
-         to clients that use the LLCC. Say yes here to enable LLCC slice
-         driver.
-
-config QCOM_SDM845_LLCC
-       tristate "Qualcomm Technologies, Inc. SDM845 LLCC driver"
-       depends on QCOM_LLCC
-       help
-         Say yes here to enable the LLCC driver for SDM845. This provides
-         data required to configure LLCC so that clients can start using the
-         LLCC slices.
+         Last Level Cache Controller(LLCC) driver for platforms such as,
+         SDM845. This provides interfaces to clients that use the LLCC.
+         Say yes here to enable LLCC slice driver.
 
 config QCOM_MDT_LOADER
        tristate
        select QCOM_SCM
 
+config QCOM_OCMEM
+       tristate "Qualcomm On Chip Memory (OCMEM) driver"
+       depends on ARCH_QCOM
+       select QCOM_SCM
+       help
+          The On Chip Memory (OCMEM) allocator allows various clients to
+          allocate memory from OCMEM based on performance, latency and power
+          requirements. This is typically used by the GPU, camera/video, and
+          audio components on some Snapdragon SoCs.
+
 config QCOM_PM
        bool "Qualcomm Power Management"
        depends on ARCH_QCOM && !ARM64
index 1627887..9fb35c8 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
 obj-$(CONFIG_QCOM_GLINK_SSR) +=        glink_ssr.o
 obj-$(CONFIG_QCOM_GSBI)        +=      qcom_gsbi.o
 obj-$(CONFIG_QCOM_MDT_LOADER)  += mdt_loader.o
+obj-$(CONFIG_QCOM_OCMEM)       += ocmem.o
 obj-$(CONFIG_QCOM_PM)  +=      spm.o
 obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
 qmi_helpers-y  += qmi_encdec.o qmi_interface.o
@@ -21,7 +22,6 @@ obj-$(CONFIG_QCOM_SMSM)       += smsm.o
 obj-$(CONFIG_QCOM_SOCINFO)     += socinfo.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
 obj-$(CONFIG_QCOM_APR) += apr.o
-obj-$(CONFIG_QCOM_LLCC) += llcc-slice.o
-obj-$(CONFIG_QCOM_SDM845_LLCC) += llcc-sdm845.o
+obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o
 obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
 obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o
similarity index 68%
rename from drivers/soc/qcom/llcc-slice.c
rename to drivers/soc/qcom/llcc-qcom.c
index 9090ea1..429b5a6 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  *
  */
 
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <linux/sizes.h>
 
 #define BANK_OFFSET_STRIDE           0x80000
 
-static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
+/**
+ * llcc_slice_config - Data associated with the llcc slice
+ * @usecase_id: Unique id for the client's use case
+ * @slice_id: llcc slice id for each client
+ * @max_cap: The maximum capacity of the cache slice provided in KB
+ * @priority: Priority of the client used to select victim line for replacement
+ * @fixed_size: Boolean indicating if the slice has a fixed capacity
+ * @bonus_ways: Bonus ways are additional ways to be used for any slice,
+ *             if client ends up using more than reserved cache ways. Bonus
+ *             ways are allocated only if they are not reserved for some
+ *             other client.
+ * @res_ways: Reserved ways for the cache slice, the reserved ways cannot
+ *             be used by any other client than the one its assigned to.
+ * @cache_mode: Each slice operates as a cache, this controls the mode of the
+ *             slice: normal or TCM(Tightly Coupled Memory)
+ * @probe_target_ways: Determines what ways to probe for access hit. When
+ *                    configured to 1 only bonus and reserved ways are probed.
+ *                    When configured to 0 all ways in llcc are probed.
+ * @dis_cap_alloc: Disable capacity based allocation for a client
+ * @retain_on_pc: If this bit is set and client has maintained active vote
+ *               then the ways assigned to this client are not flushed on power
+ *               collapse.
+ * @activate_on_init: Activate the slice immediately after it is programmed
+ */
+struct llcc_slice_config {
+       u32 usecase_id;
+       u32 slice_id;
+       u32 max_cap;
+       u32 priority;
+       bool fixed_size;
+       u32 bonus_ways;
+       u32 res_ways;
+       u32 cache_mode;
+       u32 probe_target_ways;
+       bool dis_cap_alloc;
+       bool retain_on_pc;
+       bool activate_on_init;
+};
+
+struct qcom_llcc_config {
+       const struct llcc_slice_config *sct_data;
+       int size;
+};
+
+static const struct llcc_slice_config sc7180_data[] =  {
+       { LLCC_CPUSS,    1,  256, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 1 },
+       { LLCC_MDM,      8,  128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 },
+       { LLCC_GPUHTW,   11, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 },
+       { LLCC_GPU,      12, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 },
+};
+
+static const struct llcc_slice_config sdm845_data[] =  {
+       { LLCC_CPUSS,    1,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 1 },
+       { LLCC_VIDSC0,   2,  512,  2, 1, 0x0,   0x0f0, 0, 0, 1, 1, 0 },
+       { LLCC_VIDSC1,   3,  512,  2, 1, 0x0,   0x0f0, 0, 0, 1, 1, 0 },
+       { LLCC_ROTATOR,  4,  563,  2, 1, 0x0,   0x00e, 2, 0, 1, 1, 0 },
+       { LLCC_VOICE,    5,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_AUDIO,    6,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_MDMHPGRW, 7,  1024, 2, 0, 0xfc,  0xf00, 0, 0, 1, 1, 0 },
+       { LLCC_MDM,      8,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_CMPT,     10, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_GPUHTW,   11, 512,  1, 1, 0xc,   0x0,   0, 0, 1, 1, 0 },
+       { LLCC_GPU,      12, 2304, 1, 0, 0xff0, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_MMUHWT,   13, 256,  2, 0, 0x0,   0x1,   0, 0, 1, 0, 1 },
+       { LLCC_CMPTDMA,  15, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_DISP,     16, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_VIDFW,    17, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+       { LLCC_MDMHPFX,  20, 1024, 2, 1, 0x0,   0xf00, 0, 0, 1, 1, 0 },
+       { LLCC_MDMPNG,   21, 1024, 0, 1, 0x1e,  0x0,   0, 0, 1, 1, 0 },
+       { LLCC_AUDHW,    22, 1024, 1, 1, 0xffc, 0x2,   0, 0, 1, 1, 0 },
+};
+
+static const struct qcom_llcc_config sc7180_cfg = {
+       .sct_data       = sc7180_data,
+       .size           = ARRAY_SIZE(sc7180_data),
+};
 
-static const struct regmap_config llcc_regmap_config = {
-       .reg_bits = 32,
-       .reg_stride = 4,
-       .val_bits = 32,
-       .fast_io = true,
+static const struct qcom_llcc_config sdm845_cfg = {
+       .sct_data       = sdm845_data,
+       .size           = ARRAY_SIZE(sdm845_data),
 };
 
+static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
+
 /**
  * llcc_slice_getd - get llcc slice descriptor
  * @uid: usecase_id for the client
@@ -301,19 +377,24 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
        return ret;
 }
 
-int qcom_llcc_remove(struct platform_device *pdev)
+static int qcom_llcc_remove(struct platform_device *pdev)
 {
        /* Set the global pointer to a error code to avoid referencing it */
        drv_data = ERR_PTR(-ENODEV);
        return 0;
 }
-EXPORT_SYMBOL_GPL(qcom_llcc_remove);
 
 static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
                const char *name)
 {
        struct resource *res;
        void __iomem *base;
+       struct regmap_config llcc_regmap_config = {
+               .reg_bits = 32,
+               .reg_stride = 4,
+               .val_bits = 32,
+               .fast_io = true,
+       };
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
        if (!res)
@@ -323,16 +404,19 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
        if (IS_ERR(base))
                return ERR_CAST(base);
 
+       llcc_regmap_config.name = name;
        return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config);
 }
 
-int qcom_llcc_probe(struct platform_device *pdev,
-                     const struct llcc_slice_config *llcc_cfg, u32 sz)
+static int qcom_llcc_probe(struct platform_device *pdev)
 {
        u32 num_banks;
        struct device *dev = &pdev->dev;
        int ret, i;
        struct platform_device *llcc_edac;
+       const struct qcom_llcc_config *cfg;
+       const struct llcc_slice_config *llcc_cfg;
+       u32 sz;
 
        drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
        if (!drv_data) {
@@ -362,6 +446,10 @@ int qcom_llcc_probe(struct platform_device *pdev,
        num_banks >>= LLCC_LB_CNT_SHIFT;
        drv_data->num_banks = num_banks;
 
+       cfg = of_device_get_match_data(&pdev->dev);
+       llcc_cfg = cfg->sct_data;
+       sz = cfg->size;
+
        for (i = 0; i < sz; i++)
                if (llcc_cfg[i].slice_id > drv_data->max_slices)
                        drv_data->max_slices = llcc_cfg[i].slice_id;
@@ -407,6 +495,22 @@ err:
        drv_data = ERR_PTR(-ENODEV);
        return ret;
 }
-EXPORT_SYMBOL_GPL(qcom_llcc_probe);
-MODULE_LICENSE("GPL v2");
+
+static const struct of_device_id qcom_llcc_of_match[] = {
+       { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfg },
+       { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg },
+       { }
+};
+
+static struct platform_driver qcom_llcc_driver = {
+       .driver = {
+               .name = "qcom-llcc",
+               .of_match_table = qcom_llcc_of_match,
+       },
+       .probe = qcom_llcc_probe,
+       .remove = qcom_llcc_remove,
+};
+module_platform_driver(qcom_llcc_driver);
+
 MODULE_DESCRIPTION("Qualcomm Last Level Cache Controller");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/llcc-sdm845.c b/drivers/soc/qcom/llcc-sdm845.c
deleted file mode 100644 (file)
index 86600d9..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/soc/qcom/llcc-qcom.h>
-
-/*
- * SCT(System Cache Table) entry contains of the following members:
- * usecase_id: Unique id for the client's use case
- * slice_id: llcc slice id for each client
- * max_cap: The maximum capacity of the cache slice provided in KB
- * priority: Priority of the client used to select victim line for replacement
- * fixed_size: Boolean indicating if the slice has a fixed capacity
- * bonus_ways: Bonus ways are additional ways to be used for any slice,
- *             if client ends up using more than reserved cache ways. Bonus
- *             ways are allocated only if they are not reserved for some
- *             other client.
- * res_ways: Reserved ways for the cache slice, the reserved ways cannot
- *             be used by any other client than the one its assigned to.
- * cache_mode: Each slice operates as a cache, this controls the mode of the
- *             slice: normal or TCM(Tightly Coupled Memory)
- * probe_target_ways: Determines what ways to probe for access hit. When
- *                    configured to 1 only bonus and reserved ways are probed.
- *                    When configured to 0 all ways in llcc are probed.
- * dis_cap_alloc: Disable capacity based allocation for a client
- * retain_on_pc: If this bit is set and client has maintained active vote
- *               then the ways assigned to this client are not flushed on power
- *               collapse.
- * activate_on_init: Activate the slice immediately after the SCT is programmed
- */
-#define SCT_ENTRY(uid, sid, mc, p, fs, bway, rway, cmod, ptw, dca, rp, a) \
-       {                                       \
-               .usecase_id = uid,              \
-               .slice_id = sid,                \
-               .max_cap = mc,                  \
-               .priority = p,                  \
-               .fixed_size = fs,               \
-               .bonus_ways = bway,             \
-               .res_ways = rway,               \
-               .cache_mode = cmod,             \
-               .probe_target_ways = ptw,       \
-               .dis_cap_alloc = dca,           \
-               .retain_on_pc = rp,             \
-               .activate_on_init = a,          \
-       }
-
-static struct llcc_slice_config sdm845_data[] =  {
-       SCT_ENTRY(LLCC_CPUSS,    1,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 1),
-       SCT_ENTRY(LLCC_VIDSC0,   2,  512,  2, 1, 0x0,   0x0f0, 0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_VIDSC1,   3,  512,  2, 1, 0x0,   0x0f0, 0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_ROTATOR,  4,  563,  2, 1, 0x0,   0x00e, 2, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_VOICE,    5,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_AUDIO,    6,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_MDMHPGRW, 7,  1024, 2, 0, 0xfc,  0xf00, 0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_MDM,      8,  2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_CMPT,     10, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_GPUHTW,   11, 512,  1, 1, 0xc,   0x0,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_GPU,      12, 2304, 1, 0, 0xff0, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_MMUHWT,   13, 256,  2, 0, 0x0,   0x1,   0, 0, 1, 0, 1),
-       SCT_ENTRY(LLCC_CMPTDMA,  15, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_DISP,     16, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_VIDFW,    17, 2816, 1, 0, 0xffc, 0x2,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_MDMHPFX,  20, 1024, 2, 1, 0x0,   0xf00, 0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_MDMPNG,   21, 1024, 0, 1, 0x1e,  0x0,   0, 0, 1, 1, 0),
-       SCT_ENTRY(LLCC_AUDHW,    22, 1024, 1, 1, 0xffc, 0x2,   0, 0, 1, 1, 0),
-};
-
-static int sdm845_qcom_llcc_remove(struct platform_device *pdev)
-{
-       return qcom_llcc_remove(pdev);
-}
-
-static int sdm845_qcom_llcc_probe(struct platform_device *pdev)
-{
-       return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data));
-}
-
-static const struct of_device_id sdm845_qcom_llcc_of_match[] = {
-       { .compatible = "qcom,sdm845-llcc", },
-       { }
-};
-
-static struct platform_driver sdm845_qcom_llcc_driver = {
-       .driver = {
-               .name = "sdm845-llcc",
-               .of_match_table = sdm845_qcom_llcc_of_match,
-       },
-       .probe = sdm845_qcom_llcc_probe,
-       .remove = sdm845_qcom_llcc_remove,
-};
-module_platform_driver(sdm845_qcom_llcc_driver);
-
-MODULE_DESCRIPTION("QCOM sdm845 LLCC driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
new file mode 100644 (file)
index 0000000..7f9e994
--- /dev/null
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * The On Chip Memory (OCMEM) allocator allows various clients to allocate
+ * memory from OCMEM based on performance, latency and power requirements.
+ * This is typically used by the GPU, camera/video, and audio components on
+ * some Snapdragon SoCs.
+ *
+ * Copyright (C) 2019 Brian Masney <masneyb@onstation.org>
+ * Copyright (C) 2015 Red Hat. Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/qcom_scm.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <soc/qcom/ocmem.h>
+
+enum region_mode {
+       WIDE_MODE = 0x0,
+       THIN_MODE,
+       MODE_DEFAULT = WIDE_MODE,
+};
+
+enum ocmem_macro_state {
+       PASSTHROUGH = 0,
+       PERI_ON = 1,
+       CORE_ON = 2,
+       CLK_OFF = 4,
+};
+
+struct ocmem_region {
+       bool interleaved;
+       enum region_mode mode;
+       unsigned int num_macros;
+       enum ocmem_macro_state macro_state[4];
+       unsigned long macro_size;
+       unsigned long region_size;
+};
+
+struct ocmem_config {
+       uint8_t num_regions;
+       unsigned long macro_size;
+};
+
+struct ocmem {
+       struct device *dev;
+       const struct ocmem_config *config;
+       struct resource *memory;
+       void __iomem *mmio;
+       unsigned int num_ports;
+       unsigned int num_macros;
+       bool interleaved;
+       struct ocmem_region *regions;
+       unsigned long active_allocations;
+};
+
+#define OCMEM_MIN_ALIGN                                SZ_64K
+#define OCMEM_MIN_ALLOC                                SZ_64K
+
+#define OCMEM_REG_HW_VERSION                   0x00000000
+#define OCMEM_REG_HW_PROFILE                   0x00000004
+
+#define OCMEM_REG_REGION_MODE_CTL              0x00001000
+#define OCMEM_REGION_MODE_CTL_REG0_THIN                0x00000001
+#define OCMEM_REGION_MODE_CTL_REG1_THIN                0x00000002
+#define OCMEM_REGION_MODE_CTL_REG2_THIN                0x00000004
+#define OCMEM_REGION_MODE_CTL_REG3_THIN                0x00000008
+
+#define OCMEM_REG_GFX_MPU_START                        0x00001004
+#define OCMEM_REG_GFX_MPU_END                  0x00001008
+
+#define OCMEM_HW_PROFILE_NUM_PORTS(val)                FIELD_PREP(0x0000000f, (val))
+#define OCMEM_HW_PROFILE_NUM_MACROS(val)       FIELD_PREP(0x00003f00, (val))
+
+#define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE    0x00010000
+#define OCMEM_HW_PROFILE_INTERLEAVING          0x00020000
+#define OCMEM_REG_GEN_STATUS                   0x0000000c
+
+#define OCMEM_REG_PSGSC_STATUS                 0x00000038
+#define OCMEM_REG_PSGSC_CTL(i0)                        (0x0000003c + 0x1*(i0))
+
+#define OCMEM_PSGSC_CTL_MACRO0_MODE(val)       FIELD_PREP(0x00000007, (val))
+#define OCMEM_PSGSC_CTL_MACRO1_MODE(val)       FIELD_PREP(0x00000070, (val))
+#define OCMEM_PSGSC_CTL_MACRO2_MODE(val)       FIELD_PREP(0x00000700, (val))
+#define OCMEM_PSGSC_CTL_MACRO3_MODE(val)       FIELD_PREP(0x00007000, (val))
+
+#define OCMEM_CLK_CORE_IDX                     0
+static struct clk_bulk_data ocmem_clks[] = {
+       {
+               .id = "core",
+       },
+       {
+               .id = "iface",
+       },
+};
+
+static inline void ocmem_write(struct ocmem *ocmem, u32 reg, u32 data)
+{
+       writel(data, ocmem->mmio + reg);
+}
+
+static inline u32 ocmem_read(struct ocmem *ocmem, u32 reg)
+{
+       return readl(ocmem->mmio + reg);
+}
+
+static void update_ocmem(struct ocmem *ocmem)
+{
+       uint32_t region_mode_ctrl = 0x0;
+       int i;
+
+       if (!qcom_scm_ocmem_lock_available()) {
+               for (i = 0; i < ocmem->config->num_regions; i++) {
+                       struct ocmem_region *region = &ocmem->regions[i];
+
+                       if (region->mode == THIN_MODE)
+                               region_mode_ctrl |= BIT(i);
+               }
+
+               dev_dbg(ocmem->dev, "ocmem_region_mode_control %x\n",
+                       region_mode_ctrl);
+               ocmem_write(ocmem, OCMEM_REG_REGION_MODE_CTL, region_mode_ctrl);
+       }
+
+       for (i = 0; i < ocmem->config->num_regions; i++) {
+               struct ocmem_region *region = &ocmem->regions[i];
+               u32 data;
+
+               data = OCMEM_PSGSC_CTL_MACRO0_MODE(region->macro_state[0]) |
+                       OCMEM_PSGSC_CTL_MACRO1_MODE(region->macro_state[1]) |
+                       OCMEM_PSGSC_CTL_MACRO2_MODE(region->macro_state[2]) |
+                       OCMEM_PSGSC_CTL_MACRO3_MODE(region->macro_state[3]);
+
+               ocmem_write(ocmem, OCMEM_REG_PSGSC_CTL(i), data);
+       }
+}
+
+static unsigned long phys_to_offset(struct ocmem *ocmem,
+                                   unsigned long addr)
+{
+       if (addr < ocmem->memory->start || addr >= ocmem->memory->end)
+               return 0;
+
+       return addr - ocmem->memory->start;
+}
+
+static unsigned long device_address(struct ocmem *ocmem,
+                                   enum ocmem_client client,
+                                   unsigned long addr)
+{
+       WARN_ON(client != OCMEM_GRAPHICS);
+
+       /* TODO: gpu uses phys_to_offset, but others do not.. */
+       return phys_to_offset(ocmem, addr);
+}
+
+static void update_range(struct ocmem *ocmem, struct ocmem_buf *buf,
+                        enum ocmem_macro_state mstate, enum region_mode rmode)
+{
+       unsigned long offset = 0;
+       int i, j;
+
+       for (i = 0; i < ocmem->config->num_regions; i++) {
+               struct ocmem_region *region = &ocmem->regions[i];
+
+               if (buf->offset <= offset && offset < buf->offset + buf->len)
+                       region->mode = rmode;
+
+               for (j = 0; j < region->num_macros; j++) {
+                       if (buf->offset <= offset &&
+                           offset < buf->offset + buf->len)
+                               region->macro_state[j] = mstate;
+
+                       offset += region->macro_size;
+               }
+       }
+
+       update_ocmem(ocmem);
+}
+
+struct ocmem *of_get_ocmem(struct device *dev)
+{
+       struct platform_device *pdev;
+       struct device_node *devnode;
+
+       devnode = of_parse_phandle(dev->of_node, "sram", 0);
+       if (!devnode || !devnode->parent) {
+               dev_err(dev, "Cannot look up sram phandle\n");
+               return ERR_PTR(-ENODEV);
+       }
+
+       pdev = of_find_device_by_node(devnode->parent);
+       if (!pdev) {
+               dev_err(dev, "Cannot find device node %s\n", devnode->name);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+
+       return platform_get_drvdata(pdev);
+}
+EXPORT_SYMBOL(of_get_ocmem);
+
+struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client,
+                                unsigned long size)
+{
+       struct ocmem_buf *buf;
+       int ret;
+
+       /* TODO: add support for other clients... */
+       if (WARN_ON(client != OCMEM_GRAPHICS))
+               return ERR_PTR(-ENODEV);
+
+       if (size < OCMEM_MIN_ALLOC || !IS_ALIGNED(size, OCMEM_MIN_ALIGN))
+               return ERR_PTR(-EINVAL);
+
+       if (test_and_set_bit_lock(BIT(client), &ocmem->active_allocations))
+               return ERR_PTR(-EBUSY);
+
+       buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto err_unlock;
+       }
+
+       buf->offset = 0;
+       buf->addr = device_address(ocmem, client, buf->offset);
+       buf->len = size;
+
+       update_range(ocmem, buf, CORE_ON, WIDE_MODE);
+
+       if (qcom_scm_ocmem_lock_available()) {
+               ret = qcom_scm_ocmem_lock(QCOM_SCM_OCMEM_GRAPHICS_ID,
+                                         buf->offset, buf->len, WIDE_MODE);
+               if (ret) {
+                       dev_err(ocmem->dev, "could not lock: %d\n", ret);
+                       ret = -EINVAL;
+                       goto err_kfree;
+               }
+       } else {
+               ocmem_write(ocmem, OCMEM_REG_GFX_MPU_START, buf->offset);
+               ocmem_write(ocmem, OCMEM_REG_GFX_MPU_END,
+                           buf->offset + buf->len);
+       }
+
+       dev_dbg(ocmem->dev, "using %ldK of OCMEM at 0x%08lx for client %d\n",
+               size / 1024, buf->addr, client);
+
+       return buf;
+
+err_kfree:
+       kfree(buf);
+err_unlock:
+       clear_bit_unlock(BIT(client), &ocmem->active_allocations);
+
+       return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(ocmem_allocate);
+
+void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
+               struct ocmem_buf *buf)
+{
+       /* TODO: add support for other clients... */
+       if (WARN_ON(client != OCMEM_GRAPHICS))
+               return;
+
+       update_range(ocmem, buf, CLK_OFF, MODE_DEFAULT);
+
+       if (qcom_scm_ocmem_lock_available()) {
+               int ret;
+
+               ret = qcom_scm_ocmem_unlock(QCOM_SCM_OCMEM_GRAPHICS_ID,
+                                           buf->offset, buf->len);
+               if (ret)
+                       dev_err(ocmem->dev, "could not unlock: %d\n", ret);
+       } else {
+               ocmem_write(ocmem, OCMEM_REG_GFX_MPU_START, 0x0);
+               ocmem_write(ocmem, OCMEM_REG_GFX_MPU_END, 0x0);
+       }
+
+       kfree(buf);
+
+       clear_bit_unlock(BIT(client), &ocmem->active_allocations);
+}
+EXPORT_SYMBOL(ocmem_free);
+
+static int ocmem_dev_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       unsigned long reg, region_size;
+       int i, j, ret, num_banks;
+       struct resource *res;
+       struct ocmem *ocmem;
+
+       if (!qcom_scm_is_available())
+               return -EPROBE_DEFER;
+
+       ocmem = devm_kzalloc(dev, sizeof(*ocmem), GFP_KERNEL);
+       if (!ocmem)
+               return -ENOMEM;
+
+       ocmem->dev = dev;
+       ocmem->config = device_get_match_data(dev);
+
+       ret = devm_clk_bulk_get(dev, ARRAY_SIZE(ocmem_clks), ocmem_clks);
+       if (ret) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Unable to get clocks\n");
+
+               return ret;
+       }
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+       ocmem->mmio = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(ocmem->mmio)) {
+               dev_err(&pdev->dev, "Failed to ioremap ocmem_ctrl resource\n");
+               return PTR_ERR(ocmem->mmio);
+       }
+
+       ocmem->memory = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                    "mem");
+       if (!ocmem->memory) {
+               dev_err(dev, "Could not get mem region\n");
+               return -ENXIO;
+       }
+
+       /* The core clock is synchronous with graphics */
+       WARN_ON(clk_set_rate(ocmem_clks[OCMEM_CLK_CORE_IDX].clk, 1000) < 0);
+
+       ret = clk_bulk_prepare_enable(ARRAY_SIZE(ocmem_clks), ocmem_clks);
+       if (ret) {
+               dev_info(ocmem->dev, "Failed to enable clocks\n");
+               return ret;
+       }
+
+       if (qcom_scm_restore_sec_cfg_available()) {
+               dev_dbg(dev, "configuring scm\n");
+               ret = qcom_scm_restore_sec_cfg(QCOM_SCM_OCMEM_DEV_ID, 0);
+               if (ret) {
+                       dev_err(dev, "Could not enable secure configuration\n");
+                       goto err_clk_disable;
+               }
+       }
+
+       reg = ocmem_read(ocmem, OCMEM_REG_HW_PROFILE);
+       ocmem->num_ports = OCMEM_HW_PROFILE_NUM_PORTS(reg);
+       ocmem->num_macros = OCMEM_HW_PROFILE_NUM_MACROS(reg);
+       ocmem->interleaved = !!(reg & OCMEM_HW_PROFILE_INTERLEAVING);
+
+       num_banks = ocmem->num_ports / 2;
+       region_size = ocmem->config->macro_size * num_banks;
+
+       dev_info(dev, "%u ports, %u regions, %u macros, %sinterleaved\n",
+                ocmem->num_ports, ocmem->config->num_regions,
+                ocmem->num_macros, ocmem->interleaved ? "" : "not ");
+
+       ocmem->regions = devm_kcalloc(dev, ocmem->config->num_regions,
+                                     sizeof(struct ocmem_region), GFP_KERNEL);
+       if (!ocmem->regions) {
+               ret = -ENOMEM;
+               goto err_clk_disable;
+       }
+
+       for (i = 0; i < ocmem->config->num_regions; i++) {
+               struct ocmem_region *region = &ocmem->regions[i];
+
+               if (WARN_ON(num_banks > ARRAY_SIZE(region->macro_state))) {
+                       ret = -EINVAL;
+                       goto err_clk_disable;
+               }
+
+               region->mode = MODE_DEFAULT;
+               region->num_macros = num_banks;
+
+               if (i == (ocmem->config->num_regions - 1) &&
+                   reg & OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE) {
+                       region->macro_size = ocmem->config->macro_size / 2;
+                       region->region_size = region_size / 2;
+               } else {
+                       region->macro_size = ocmem->config->macro_size;
+                       region->region_size = region_size;
+               }
+
+               for (j = 0; j < ARRAY_SIZE(region->macro_state); j++)
+                       region->macro_state[j] = CLK_OFF;
+       }
+
+       platform_set_drvdata(pdev, ocmem);
+
+       return 0;
+
+err_clk_disable:
+       clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks);
+       return ret;
+}
+
+static int ocmem_dev_remove(struct platform_device *pdev)
+{
+       clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks);
+
+       return 0;
+}
+
+static const struct ocmem_config ocmem_8974_config = {
+       .num_regions = 3,
+       .macro_size = SZ_128K,
+};
+
+static const struct of_device_id ocmem_of_match[] = {
+       { .compatible = "qcom,msm8974-ocmem", .data = &ocmem_8974_config },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, ocmem_of_match);
+
+static struct platform_driver ocmem_driver = {
+       .probe = ocmem_dev_probe,
+       .remove = ocmem_dev_remove,
+       .driver = {
+               .name = "ocmem",
+               .of_match_table = ocmem_of_match,
+       },
+};
+
+module_platform_driver(ocmem_driver);
+
+MODULE_DESCRIPTION("On Chip Memory (OCMEM) allocator for some Snapdragon SoCs");
+MODULE_LICENSE("GPL v2");
index 33a27e6..006ac40 100644 (file)
@@ -44,7 +44,7 @@
 
 #define QMP_NUM_COOLING_RESOURCES      2
 
-static bool qmp_cdev_init_state = 1;
+static bool qmp_cdev_max_state = 1;
 
 struct qmp_cooling_device {
        struct thermal_cooling_device *cdev;
@@ -402,7 +402,7 @@ static void qmp_pd_remove(struct qmp *qmp)
 static int qmp_cdev_get_max_state(struct thermal_cooling_device *cdev,
                                  unsigned long *state)
 {
-       *state = qmp_cdev_init_state;
+       *state = qmp_cdev_max_state;
        return 0;
 }
 
@@ -432,7 +432,7 @@ static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev,
        snprintf(buf, sizeof(buf),
                 "{class: volt_flr, event:zero_temp, res:%s, value:%s}",
                        qmp_cdev->name,
-                       cdev_state ? "off" : "on");
+                       cdev_state ? "on" : "off");
 
        ret = qmp_send(qmp_cdev->qmp, buf, sizeof(buf));
 
@@ -455,7 +455,7 @@ static int qmp_cooling_device_add(struct qmp *qmp,
        char *cdev_name = (char *)node->name;
 
        qmp_cdev->qmp = qmp;
-       qmp_cdev->state = qmp_cdev_init_state;
+       qmp_cdev->state = !qmp_cdev_max_state;
        qmp_cdev->name = cdev_name;
        qmp_cdev->cdev = devm_thermal_of_cooling_device_register
                                (qmp->dev, node,
index 3c1a55c..2b1834c 100644 (file)
@@ -115,6 +115,28 @@ struct rpmpd_desc {
 
 static DEFINE_MUTEX(rpmpd_lock);
 
+/* msm8976 RPM Power Domains */
+DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2);
+DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6);
+
+DEFINE_RPMPD_VFL(msm8976, vddcx_vfl, RWSC, 2);
+DEFINE_RPMPD_VFL(msm8976, vddmx_vfl, RWSM, 6);
+
+static struct rpmpd *msm8976_rpmpds[] = {
+       [MSM8976_VDDCX] =       &msm8976_vddcx,
+       [MSM8976_VDDCX_AO] =    &msm8976_vddcx_ao,
+       [MSM8976_VDDCX_VFL] =   &msm8976_vddcx_vfl,
+       [MSM8976_VDDMX] =       &msm8976_vddmx,
+       [MSM8976_VDDMX_AO] =    &msm8976_vddmx_ao,
+       [MSM8976_VDDMX_VFL] =   &msm8976_vddmx_vfl,
+};
+
+static const struct rpmpd_desc msm8976_desc = {
+       .rpmpds = msm8976_rpmpds,
+       .num_pds = ARRAY_SIZE(msm8976_rpmpds),
+       .max_state = RPM_SMD_LEVEL_TURBO_HIGH,
+};
+
 /* msm8996 RPM Power domains */
 DEFINE_RPMPD_PAIR(msm8996, vddcx, vddcx_ao, SMPA, CORNER, 1);
 DEFINE_RPMPD_PAIR(msm8996, vddmx, vddmx_ao, SMPA, CORNER, 2);
@@ -198,6 +220,7 @@ static const struct rpmpd_desc qcs404_desc = {
 };
 
 static const struct of_device_id rpmpd_match_table[] = {
+       { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc },
        { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc },
        { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc },
        { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc },
index fa9dd12..005dd30 100644 (file)
 /**
  * struct qcom_smd_rpm - state of the rpm device driver
  * @rpm_channel:       reference to the smd channel
+ * @icc:               interconnect proxy device
  * @ack:               completion for acks
  * @lock:              mutual exclusion around the send/complete pair
  * @ack_status:                result of the rpm request
  */
 struct qcom_smd_rpm {
        struct rpmsg_endpoint *rpm_channel;
+       struct platform_device *icc;
        struct device *dev;
 
        struct completion ack;
@@ -193,6 +195,7 @@ static int qcom_smd_rpm_callback(struct rpmsg_device *rpdev,
 static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
 {
        struct qcom_smd_rpm *rpm;
+       int ret;
 
        rpm = devm_kzalloc(&rpdev->dev, sizeof(*rpm), GFP_KERNEL);
        if (!rpm)
@@ -205,11 +208,23 @@ static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
        rpm->rpm_channel = rpdev->ept;
        dev_set_drvdata(&rpdev->dev, rpm);
 
-       return of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev);
+       rpm->icc = platform_device_register_data(&rpdev->dev, "icc_smd_rpm", -1,
+                                                NULL, 0);
+       if (IS_ERR(rpm->icc))
+               return PTR_ERR(rpm->icc);
+
+       ret = of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev);
+       if (ret)
+               platform_device_unregister(rpm->icc);
+
+       return ret;
 }
 
 static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev)
 {
+       struct qcom_smd_rpm *rpm = dev_get_drvdata(&rpdev->dev);
+
+       platform_device_unregister(rpm->icc);
        of_platform_depopulate(&rpdev->dev);
 }
 
@@ -217,6 +232,7 @@ static const struct of_device_id qcom_smd_rpm_of_match[] = {
        { .compatible = "qcom,rpm-apq8084" },
        { .compatible = "qcom,rpm-msm8916" },
        { .compatible = "qcom,rpm-msm8974" },
+       { .compatible = "qcom,rpm-msm8976" },
        { .compatible = "qcom,rpm-msm8996" },
        { .compatible = "qcom,rpm-msm8998" },
        { .compatible = "qcom,rpm-sdm660" },
index a39ea50..7864b75 100644 (file)
@@ -198,6 +198,8 @@ static const struct soc_id soc_id[] = {
        { 310, "MSM8996AU" },
        { 311, "APQ8096AU" },
        { 312, "APQ8096SG" },
+       { 321, "SDM845" },
+       { 341, "SDA845" },
 };
 
 static const char *socinfo_machine(struct device *dev, unsigned int id)
index 3c5e017..f93492b 100644 (file)
@@ -178,6 +178,13 @@ config ARCH_R8A774A1
        help
          This enables support for the Renesas RZ/G2M SoC.
 
+config ARCH_R8A774B1
+       bool "Renesas RZ/G2N SoC Platform"
+       select ARCH_RCAR_GEN3
+       select SYSC_R8A774B1
+       help
+         This enables support for the Renesas RZ/G2N SoC.
+
 config ARCH_R8A774C0
        bool "Renesas RZ/G2E SoC Platform"
        select ARCH_RCAR_GEN3
@@ -192,13 +199,24 @@ config ARCH_R8A7795
        help
          This enables support for the Renesas R-Car H3 SoC.
 
+config ARCH_R8A77960
+       bool
+       select ARCH_RCAR_GEN3
+       select SYSC_R8A77960
+
 config ARCH_R8A7796
        bool "Renesas R-Car M3-W SoC Platform"
-       select ARCH_RCAR_GEN3
-       select SYSC_R8A7796
+       select ARCH_R8A77960
        help
          This enables support for the Renesas R-Car M3-W SoC.
 
+config ARCH_R8A77961
+       bool "Renesas R-Car M3-W+ SoC Platform"
+       select ARCH_RCAR_GEN3
+       select SYSC_R8A77961
+       help
+         This enables support for the Renesas R-Car M3-W+ SoC.
+
 config ARCH_R8A77965
        bool "Renesas R-Car M3-N SoC Platform"
        select ARCH_RCAR_GEN3
@@ -253,6 +271,10 @@ config SYSC_R8A774A1
        bool "RZ/G2M System Controller support" if COMPILE_TEST
        select SYSC_RCAR
 
+config SYSC_R8A774B1
+       bool "RZ/G2N System Controller support" if COMPILE_TEST
+       select SYSC_RCAR
+
 config SYSC_R8A774C0
        bool "RZ/G2E System Controller support" if COMPILE_TEST
        select SYSC_RCAR
@@ -281,10 +303,14 @@ config SYSC_R8A7795
        bool "R-Car H3 System Controller support" if COMPILE_TEST
        select SYSC_RCAR
 
-config SYSC_R8A7796
+config SYSC_R8A77960
        bool "R-Car M3-W System Controller support" if COMPILE_TEST
        select SYSC_RCAR
 
+config SYSC_R8A77961
+       bool "R-Car M3-W+ System Controller support" if COMPILE_TEST
+       select SYSC_RCAR
+
 config SYSC_R8A77965
        bool "R-Car M3-N System Controller support" if COMPILE_TEST
        select SYSC_RCAR
index 00764d5..e595c3c 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_SYSC_R8A7743)      += r8a7743-sysc.o
 obj-$(CONFIG_SYSC_R8A7745)     += r8a7745-sysc.o
 obj-$(CONFIG_SYSC_R8A77470)    += r8a77470-sysc.o
 obj-$(CONFIG_SYSC_R8A774A1)    += r8a774a1-sysc.o
+obj-$(CONFIG_SYSC_R8A774B1)    += r8a774b1-sysc.o
 obj-$(CONFIG_SYSC_R8A774C0)    += r8a774c0-sysc.o
 obj-$(CONFIG_SYSC_R8A7779)     += r8a7779-sysc.o
 obj-$(CONFIG_SYSC_R8A7790)     += r8a7790-sysc.o
@@ -14,7 +15,8 @@ obj-$(CONFIG_SYSC_R8A7791)    += r8a7791-sysc.o
 obj-$(CONFIG_SYSC_R8A7792)     += r8a7792-sysc.o
 obj-$(CONFIG_SYSC_R8A7794)     += r8a7794-sysc.o
 obj-$(CONFIG_SYSC_R8A7795)     += r8a7795-sysc.o
-obj-$(CONFIG_SYSC_R8A7796)     += r8a7796-sysc.o
+obj-$(CONFIG_SYSC_R8A77960)    += r8a7796-sysc.o
+obj-$(CONFIG_SYSC_R8A77961)    += r8a7796-sysc.o
 obj-$(CONFIG_SYSC_R8A77965)    += r8a77965-sysc.o
 obj-$(CONFIG_SYSC_R8A77970)    += r8a77970-sysc.o
 obj-$(CONFIG_SYSC_R8A77980)    += r8a77980-sysc.o
index edf6436..4e2c0ab 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Cogent Embedded Inc.
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a7743-sysc.h>
index 65dc6b0..865821a 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Cogent Embedded Inc.
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a7745-sysc.h>
index cfa015e..1eeb801 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Renesas Electronics Corp.
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a77470-sysc.h>
index 9db51ff..38ac2c6 100644 (file)
@@ -7,7 +7,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a774a1-sysc.h>
diff --git a/drivers/soc/renesas/r8a774b1-sysc.c b/drivers/soc/renesas/r8a774b1-sysc.c
new file mode 100644 (file)
index 0000000..5f97ff2
--- /dev/null
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G2N System Controller
+ * Copyright (C) 2019 Renesas Electronics Corp.
+ *
+ * Based on Renesas R-Car M3-W System Controller
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#include <linux/bits.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a774b1-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a774b1_areas[] __initconst = {
+       { "always-on",      0, 0, R8A774B1_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+       { "ca57-scu",   0x1c0, 0, R8A774B1_PD_CA57_SCU, R8A774B1_PD_ALWAYS_ON,
+         PD_SCU },
+       { "ca57-cpu0",   0x80, 0, R8A774B1_PD_CA57_CPU0, R8A774B1_PD_CA57_SCU,
+         PD_CPU_NOCR },
+       { "ca57-cpu1",   0x80, 1, R8A774B1_PD_CA57_CPU1, R8A774B1_PD_CA57_SCU,
+         PD_CPU_NOCR },
+       { "a3vc",       0x380, 0, R8A774B1_PD_A3VC,     R8A774B1_PD_ALWAYS_ON },
+       { "a3vp",       0x340, 0, R8A774B1_PD_A3VP,     R8A774B1_PD_ALWAYS_ON },
+       { "a2vc1",      0x3c0, 1, R8A774B1_PD_A2VC1,    R8A774B1_PD_A3VC },
+       { "3dg-a",      0x100, 0, R8A774B1_PD_3DG_A,    R8A774B1_PD_ALWAYS_ON },
+       { "3dg-b",      0x100, 1, R8A774B1_PD_3DG_B,    R8A774B1_PD_3DG_A },
+};
+
+const struct rcar_sysc_info r8a774b1_sysc_info __initconst = {
+       .areas = r8a774b1_areas,
+       .num_areas = ARRAY_SIZE(r8a774b1_areas),
+       .extmask_offs = 0x2f8,
+       .extmask_val = BIT(0),
+};
index 11050e1..c1c216f 100644 (file)
@@ -6,7 +6,7 @@
  * Based on Renesas R-Car E3 System Controller
  */
 
-#include <linux/bug.h>
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/sys_soc.h>
 
@@ -50,4 +50,6 @@ const struct rcar_sysc_info r8a774c0_sysc_info __initconst = {
        .init = r8a774c0_sysc_init,
        .areas = r8a774c0_areas,
        .num_areas = ARRAY_SIZE(r8a774c0_areas),
+       .extmask_offs = 0x2f8,
+       .extmask_val = BIT(0),
 };
index 517aa40..e24a715 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a7779-sysc.h>
index 9b5a6bb..b9afe7f 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a7790-sysc.h>
index acf545c..f00fa24 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a7791-sysc.h>
index 05b7852..60aae24 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Cogent Embedded Inc.
  */
 
-#include <linux/bug.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 
index 0d42637..72ef4e8 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a7794-sysc.h>
index cda27a6..9107441 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2016-2017 Glider bvba
  */
 
-#include <linux/bug.h>
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/sys_soc.h>
 
@@ -51,25 +51,46 @@ static struct rcar_sysc_area r8a7795_areas[] __initdata = {
 
 
        /*
-        * Fixups for R-Car H3 revisions after ES1.x
+        * Fixups for R-Car H3 revisions
         */
 
-static const struct soc_device_attribute r8a7795es1[] __initconst = {
-       { .soc_id = "r8a7795", .revision = "ES1.*" },
+#define HAS_A2VC0      BIT(0)          /* Power domain A2VC0 is present */
+#define NO_EXTMASK     BIT(1)          /* Missing SYSCEXTMASK register */
+
+static const struct soc_device_attribute r8a7795_quirks_match[] __initconst = {
+       {
+               .soc_id = "r8a7795", .revision = "ES1.*",
+               .data = (void *)(HAS_A2VC0 | NO_EXTMASK),
+       }, {
+               .soc_id = "r8a7795", .revision = "ES2.*",
+               .data = (void *)(NO_EXTMASK),
+       },
        { /* sentinel */ }
 };
 
 static int __init r8a7795_sysc_init(void)
 {
-       if (!soc_device_match(r8a7795es1))
+       const struct soc_device_attribute *attr;
+       u32 quirks = 0;
+
+       attr = soc_device_match(r8a7795_quirks_match);
+       if (attr)
+               quirks = (uintptr_t)attr->data;
+
+       if (!(quirks & HAS_A2VC0))
                rcar_sysc_nullify(r8a7795_areas, ARRAY_SIZE(r8a7795_areas),
                                  R8A7795_PD_A2VC0);
 
+       if (quirks & NO_EXTMASK)
+               r8a7795_sysc_info.extmask_val = 0;
+
        return 0;
 }
 
-const struct rcar_sysc_info r8a7795_sysc_info __initconst = {
+struct rcar_sysc_info r8a7795_sysc_info __initdata = {
        .init = r8a7795_sysc_init,
        .areas = r8a7795_areas,
        .num_areas = ARRAY_SIZE(r8a7795_areas),
+       .extmask_offs = 0x2f8,
+       .extmask_val = BIT(0),
 };
index 1b06f86..471bd5b 100644 (file)
@@ -1,18 +1,19 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Renesas R-Car M3-W System Controller
+ * Renesas R-Car M3-W/W+ System Controller
  *
  * Copyright (C) 2016 Glider bvba
+ * Copyright (C) 2018-2019 Renesas Electronics Corporation
  */
 
-#include <linux/bug.h>
+#include <linux/bits.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a7796-sysc.h>
 
 #include "rcar-sysc.h"
 
-static const struct rcar_sysc_area r8a7796_areas[] __initconst = {
+static struct rcar_sysc_area r8a7796_areas[] __initdata = {
        { "always-on",      0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
        { "ca57-scu",   0x1c0, 0, R8A7796_PD_CA57_SCU,  R8A7796_PD_ALWAYS_ON,
          PD_SCU },
@@ -39,7 +40,28 @@ static const struct rcar_sysc_area r8a7796_areas[] __initconst = {
        { "a3ir",       0x180, 0, R8A7796_PD_A3IR,      R8A7796_PD_ALWAYS_ON },
 };
 
-const struct rcar_sysc_info r8a7796_sysc_info __initconst = {
+
+#ifdef CONFIG_SYSC_R8A77960
+const struct rcar_sysc_info r8a77960_sysc_info __initconst = {
+       .areas = r8a7796_areas,
+       .num_areas = ARRAY_SIZE(r8a7796_areas),
+};
+#endif /* CONFIG_SYSC_R8A77960 */
+
+#ifdef CONFIG_SYSC_R8A77961
+static int __init r8a77961_sysc_init(void)
+{
+       rcar_sysc_nullify(r8a7796_areas, ARRAY_SIZE(r8a7796_areas),
+                         R8A7796_PD_A2VC0);
+
+       return 0;
+}
+
+const struct rcar_sysc_info r8a77961_sysc_info __initconst = {
+       .init = r8a77961_sysc_init,
        .areas = r8a7796_areas,
        .num_areas = ARRAY_SIZE(r8a7796_areas),
+       .extmask_offs = 0x2f8,
+       .extmask_val = BIT(0),
 };
+#endif /* CONFIG_SYSC_R8A77961 */
index e0533be..ff0b0d1 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <linux/bug.h>
+#include <linux/bits.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a77965-sysc.h>
@@ -33,4 +33,6 @@ static const struct rcar_sysc_area r8a77965_areas[] __initconst = {
 const struct rcar_sysc_info r8a77965_sysc_info __initconst = {
        .areas = r8a77965_areas,
        .num_areas = ARRAY_SIZE(r8a77965_areas),
+       .extmask_offs = 0x2f8,
+       .extmask_val = BIT(0),
 };
index 280c48b..7062582 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2017 Cogent Embedded Inc.
  */
 
-#include <linux/bug.h>
+#include <linux/bits.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a77970-sysc.h>
@@ -32,4 +32,6 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = {
 const struct rcar_sysc_info r8a77970_sysc_info __initconst = {
        .areas = r8a77970_areas,
        .num_areas = ARRAY_SIZE(r8a77970_areas),
+       .extmask_offs = 0x1b0,
+       .extmask_val = BIT(0),
 };
index a8dbe55..39ca84a 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2018 Cogent Embedded, Inc.
  */
 
-#include <linux/bug.h>
+#include <linux/bits.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a77980-sysc.h>
@@ -49,4 +49,6 @@ static const struct rcar_sysc_area r8a77980_areas[] __initconst = {
 const struct rcar_sysc_info r8a77980_sysc_info __initconst = {
        .areas = r8a77980_areas,
        .num_areas = ARRAY_SIZE(r8a77980_areas),
+       .extmask_offs = 0x138,
+       .extmask_val = BIT(0),
 };
index 664b244..9f92737 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2018 Renesas Electronics Corp.
  */
 
-#include <linux/bug.h>
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/sys_soc.h>
 
@@ -50,4 +50,6 @@ const struct rcar_sysc_info r8a77990_sysc_info __initconst = {
        .init = r8a77990_sysc_init,
        .areas = r8a77990_areas,
        .num_areas = ARRAY_SIZE(r8a77990_areas),
+       .extmask_offs = 0x2f8,
+       .extmask_val = BIT(0),
 };
index 6243aaa..efcc67e 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 2017 Glider bvba
  */
 
-#include <linux/bug.h>
 #include <linux/kernel.h>
 
 #include <dt-bindings/power/r8a77995-sysc.h>
index d183c38..14d05a0 100644 (file)
@@ -45,6 +45,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
        { .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 },
        /* RZ/G2 is handled like R-Car Gen3 */
        { .compatible = "renesas,r8a774a1-rst", .data = &rcar_rst_gen3 },
+       { .compatible = "renesas,r8a774b1-rst", .data = &rcar_rst_gen3 },
        { .compatible = "renesas,r8a774c0-rst", .data = &rcar_rst_gen3 },
        /* R-Car Gen1 */
        { .compatible = "renesas,r8a7778-reset-wdt", .data = &rcar_rst_gen1 },
@@ -58,6 +59,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
        /* R-Car Gen3 */
        { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen3 },
        { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen3 },
+       { .compatible = "renesas,r8a77961-rst", .data = &rcar_rst_gen3 },
        { .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen3 },
        { .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen3 },
        { .compatible = "renesas,r8a77980-rst", .data = &rcar_rst_gen3 },
index 59b5e6b..f0b291e 100644 (file)
@@ -63,6 +63,7 @@ struct rcar_sysc_ch {
 
 static void __iomem *rcar_sysc_base;
 static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
+static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val;
 
 static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
 {
@@ -106,6 +107,14 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
        spin_lock_irqsave(&rcar_sysc_lock, flags);
 
        /*
+        * Mask external power requests for CPU or 3DG domains
+        */
+       if (rcar_sysc_extmask_val) {
+               iowrite32(rcar_sysc_extmask_val,
+                         rcar_sysc_base + rcar_sysc_extmask_offs);
+       }
+
+       /*
         * The interrupt source needs to be enabled, but masked, to prevent the
         * CPU from receiving it.
         */
@@ -148,6 +157,9 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
        iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
 
  out:
+       if (rcar_sysc_extmask_val)
+               iowrite32(0, rcar_sysc_base + rcar_sysc_extmask_offs);
+
        spin_unlock_irqrestore(&rcar_sysc_lock, flags);
 
        pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off",
@@ -275,6 +287,9 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = {
 #ifdef CONFIG_SYSC_R8A774A1
        { .compatible = "renesas,r8a774a1-sysc", .data = &r8a774a1_sysc_info },
 #endif
+#ifdef CONFIG_SYSC_R8A774B1
+       { .compatible = "renesas,r8a774b1-sysc", .data = &r8a774b1_sysc_info },
+#endif
 #ifdef CONFIG_SYSC_R8A774C0
        { .compatible = "renesas,r8a774c0-sysc", .data = &r8a774c0_sysc_info },
 #endif
@@ -298,8 +313,11 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = {
 #ifdef CONFIG_SYSC_R8A7795
        { .compatible = "renesas,r8a7795-sysc", .data = &r8a7795_sysc_info },
 #endif
-#ifdef CONFIG_SYSC_R8A7796
-       { .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info },
+#ifdef CONFIG_SYSC_R8A77960
+       { .compatible = "renesas,r8a7796-sysc", .data = &r8a77960_sysc_info },
+#endif
+#ifdef CONFIG_SYSC_R8A77961
+       { .compatible = "renesas,r8a77961-sysc", .data = &r8a77961_sysc_info },
 #endif
 #ifdef CONFIG_SYSC_R8A77965
        { .compatible = "renesas,r8a77965-sysc", .data = &r8a77965_sysc_info },
@@ -360,6 +378,10 @@ static int __init rcar_sysc_pd_init(void)
 
        rcar_sysc_base = base;
 
+       /* Optional External Request Mask Register */
+       rcar_sysc_extmask_offs = info->extmask_offs;
+       rcar_sysc_extmask_val = info->extmask_val;
+
        domains = kzalloc(sizeof(*domains), GFP_KERNEL);
        if (!domains) {
                error = -ENOMEM;
index 485520a..8d07448 100644 (file)
@@ -44,20 +44,25 @@ struct rcar_sysc_info {
        int (*init)(void);      /* Optional */
        const struct rcar_sysc_area *areas;
        unsigned int num_areas;
+       /* Optional External Request Mask Register */
+       u32 extmask_offs;       /* SYSCEXTMASK register offset */
+       u32 extmask_val;        /* SYSCEXTMASK register mask value */
 };
 
 extern const struct rcar_sysc_info r8a7743_sysc_info;
 extern const struct rcar_sysc_info r8a7745_sysc_info;
 extern const struct rcar_sysc_info r8a77470_sysc_info;
 extern const struct rcar_sysc_info r8a774a1_sysc_info;
+extern const struct rcar_sysc_info r8a774b1_sysc_info;
 extern const struct rcar_sysc_info r8a774c0_sysc_info;
 extern const struct rcar_sysc_info r8a7779_sysc_info;
 extern const struct rcar_sysc_info r8a7790_sysc_info;
 extern const struct rcar_sysc_info r8a7791_sysc_info;
 extern const struct rcar_sysc_info r8a7792_sysc_info;
 extern const struct rcar_sysc_info r8a7794_sysc_info;
-extern const struct rcar_sysc_info r8a7795_sysc_info;
-extern const struct rcar_sysc_info r8a7796_sysc_info;
+extern struct rcar_sysc_info r8a7795_sysc_info;
+extern const struct rcar_sysc_info r8a77960_sysc_info;
+extern const struct rcar_sysc_info r8a77961_sysc_info;
 extern const struct rcar_sysc_info r8a77965_sysc_info;
 extern const struct rcar_sysc_info r8a77970_sysc_info;
 extern const struct rcar_sysc_info r8a77980_sysc_info;
index 3299cf5..850f573 100644 (file)
@@ -116,6 +116,11 @@ static const struct renesas_soc soc_rz_g2m __initconst __maybe_unused = {
        .id     = 0x52,
 };
 
+static const struct renesas_soc soc_rz_g2n __initconst __maybe_unused = {
+       .family = &fam_rzg2,
+       .id     = 0x55,
+};
+
 static const struct renesas_soc soc_rz_g2e __initconst __maybe_unused = {
        .family = &fam_rzg2,
        .id     = 0x57,
@@ -227,6 +232,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #ifdef CONFIG_ARCH_R8A774A1
        { .compatible = "renesas,r8a774a1",     .data = &soc_rz_g2m },
 #endif
+#ifdef CONFIG_ARCH_R8A774B1
+       { .compatible = "renesas,r8a774b1",     .data = &soc_rz_g2n },
+#endif
 #ifdef CONFIG_ARCH_R8A774C0
        { .compatible = "renesas,r8a774c0",     .data = &soc_rz_g2e },
 #endif
@@ -254,9 +262,12 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #ifdef CONFIG_ARCH_R8A7795
        { .compatible = "renesas,r8a7795",      .data = &soc_rcar_h3 },
 #endif
-#ifdef CONFIG_ARCH_R8A7796
+#ifdef CONFIG_ARCH_R8A77960
        { .compatible = "renesas,r8a7796",      .data = &soc_rcar_m3_w },
 #endif
+#ifdef CONFIG_ARCH_R8A77961
+       { .compatible = "renesas,r8a77961",     .data = &soc_rcar_m3_w },
+#endif
 #ifdef CONFIG_ARCH_R8A77965
        { .compatible = "renesas,r8a77965",     .data = &soc_rcar_m3_n },
 #endif
@@ -326,7 +337,7 @@ static int __init renesas_soc_init(void)
        if (np) {
                chipid = of_iomap(np, 0);
                of_node_put(np);
-       } else if (soc->id) {
+       } else if (soc->id && family->reg) {
                chipid = ioremap(family->reg, 4);
        }
        if (chipid) {
index 33ad0de..27fc59b 100644 (file)
@@ -7,6 +7,16 @@ menuconfig SOC_SAMSUNG
 
 if SOC_SAMSUNG
 
+config EXYNOS_ASV
+       bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
+       depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST
+       select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
+
+# There is no need to enable these drivers for ARMv8
+config EXYNOS_ASV_ARM
+       bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
+       depends on EXYNOS_ASV
+
 config EXYNOS_CHIPID
        bool "Exynos Chipid controller driver" if COMPILE_TEST
        depends on ARCH_EXYNOS || COMPILE_TEST
index 3b6a879..edd1d6e 100644 (file)
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_EXYNOS_ASV)       += exynos-asv.o
+obj-$(CONFIG_EXYNOS_ASV_ARM)   += exynos5422-asv.o
+
 obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
 
diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
new file mode 100644 (file)
index 0000000..30bb7b7
--- /dev/null
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/cpu.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+
+#include "exynos-asv.h"
+#include "exynos5422-asv.h"
+
+#define MHZ 1000000U
+
+static int exynos_asv_update_cpu_opps(struct exynos_asv *asv,
+                                     struct device *cpu)
+{
+       struct exynos_asv_subsys *subsys = NULL;
+       struct dev_pm_opp *opp;
+       unsigned int opp_freq;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) {
+               if (of_device_is_compatible(cpu->of_node,
+                                           asv->subsys[i].cpu_dt_compat)) {
+                       subsys = &asv->subsys[i];
+                       break;
+               }
+       }
+       if (!subsys)
+               return -EINVAL;
+
+       for (i = 0; i < subsys->table.num_rows; i++) {
+               unsigned int new_volt, volt;
+               int ret;
+
+               opp_freq = exynos_asv_opp_get_frequency(subsys, i);
+
+               opp = dev_pm_opp_find_freq_exact(cpu, opp_freq * MHZ, true);
+               if (IS_ERR(opp)) {
+                       dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
+                                cpu->id, i, opp_freq);
+
+                       continue;
+               }
+
+               volt = dev_pm_opp_get_voltage(opp);
+               new_volt = asv->opp_get_voltage(subsys, i, volt);
+               dev_pm_opp_put(opp);
+
+               if (new_volt == volt)
+                       continue;
+
+               ret = dev_pm_opp_adjust_voltage(cpu, opp_freq * MHZ,
+                                               new_volt, new_volt, new_volt);
+               if (ret < 0)
+                       dev_err(asv->dev,
+                               "Failed to adjust OPP %u Hz/%u uV for cpu%d\n",
+                               opp_freq, new_volt, cpu->id);
+               else
+                       dev_dbg(asv->dev,
+                               "Adjusted OPP %u Hz/%u -> %u uV, cpu%d\n",
+                               opp_freq, volt, new_volt, cpu->id);
+       }
+
+       return 0;
+}
+
+static int exynos_asv_update_opps(struct exynos_asv *asv)
+{
+       struct opp_table *last_opp_table = NULL;
+       struct device *cpu;
+       int ret, cpuid;
+
+       for_each_possible_cpu(cpuid) {
+               struct opp_table *opp_table;
+
+               cpu = get_cpu_device(cpuid);
+               if (!cpu)
+                       continue;
+
+               opp_table = dev_pm_opp_get_opp_table(cpu);
+               if (IS_ERR_OR_NULL(opp_table))
+                       continue;
+
+               if (!last_opp_table || opp_table != last_opp_table) {
+                       last_opp_table = opp_table;
+
+                       ret = exynos_asv_update_cpu_opps(asv, cpu);
+                       if (ret < 0)
+                               dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
+                                       cpuid);
+               }
+
+               dev_pm_opp_put_opp_table(opp_table);
+       }
+
+       return  0;
+}
+
+static int exynos_asv_probe(struct platform_device *pdev)
+{
+       int (*probe_func)(struct exynos_asv *asv);
+       struct exynos_asv *asv;
+       struct device *cpu_dev;
+       u32 product_id = 0;
+       int ret, i;
+
+       cpu_dev = get_cpu_device(0);
+       ret = dev_pm_opp_get_opp_count(cpu_dev);
+       if (ret < 0)
+               return -EPROBE_DEFER;
+
+       asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
+       if (!asv)
+               return -ENOMEM;
+
+       asv->chipid_regmap = device_node_to_regmap(pdev->dev.of_node);
+       if (IS_ERR(asv->chipid_regmap)) {
+               dev_err(&pdev->dev, "Could not find syscon regmap\n");
+               return PTR_ERR(asv->chipid_regmap);
+       }
+
+       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
+
+       switch (product_id & EXYNOS_MASK) {
+       case 0xE5422000:
+               probe_func = exynos5422_asv_init;
+               break;
+       default:
+               return -ENODEV;
+       }
+
+       ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
+                                  &asv->of_bin);
+       if (ret < 0)
+               asv->of_bin = -EINVAL;
+
+       asv->dev = &pdev->dev;
+       dev_set_drvdata(&pdev->dev, asv);
+
+       for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
+               asv->subsys[i].asv = asv;
+
+       ret = probe_func(asv);
+       if (ret < 0)
+               return ret;
+
+       return exynos_asv_update_opps(asv);
+}
+
+static const struct of_device_id exynos_asv_of_device_ids[] = {
+       { .compatible = "samsung,exynos4210-chipid" },
+       {}
+};
+
+static struct platform_driver exynos_asv_driver = {
+       .driver = {
+               .name = "exynos-asv",
+               .of_match_table = exynos_asv_of_device_ids,
+       },
+       .probe  = exynos_asv_probe,
+};
+module_platform_driver(exynos_asv_driver);
diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
new file mode 100644 (file)
index 0000000..3fd1f2a
--- /dev/null
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung Exynos SoC Adaptive Supply Voltage support
+ */
+#ifndef __LINUX_SOC_EXYNOS_ASV_H
+#define __LINUX_SOC_EXYNOS_ASV_H
+
+struct regmap;
+
+/* HPM, IDS values to select target group */
+struct asv_limit_entry {
+       unsigned int hpm;
+       unsigned int ids;
+};
+
+struct exynos_asv_table {
+       unsigned int num_rows;
+       unsigned int num_cols;
+       u32 *buf;
+};
+
+struct exynos_asv_subsys {
+       struct exynos_asv *asv;
+       const char *cpu_dt_compat;
+       int id;
+       struct exynos_asv_table table;
+
+       unsigned int base_volt;
+       unsigned int offset_volt_h;
+       unsigned int offset_volt_l;
+};
+
+struct exynos_asv {
+       struct device *dev;
+       struct regmap *chipid_regmap;
+       struct exynos_asv_subsys subsys[2];
+
+       int (*opp_get_voltage)(const struct exynos_asv_subsys *subs,
+                              int level, unsigned int voltage);
+       unsigned int group;
+       unsigned int table;
+
+       /* True if SG fields from PKG_ID register should be used */
+       bool use_sg;
+       /* ASV bin read from DT */
+       int of_bin;
+};
+
+static inline u32 __asv_get_table_entry(const struct exynos_asv_table *table,
+                                       unsigned int row, unsigned int col)
+{
+       return table->buf[row * (table->num_cols) + col];
+}
+
+static inline u32 exynos_asv_opp_get_voltage(const struct exynos_asv_subsys *subsys,
+                                       unsigned int level, unsigned int group)
+{
+       return __asv_get_table_entry(&subsys->table, level, group + 1);
+}
+
+static inline u32 exynos_asv_opp_get_frequency(const struct exynos_asv_subsys *subsys,
+                                       unsigned int level)
+{
+       return __asv_get_table_entry(&subsys->table, level, 0);
+}
+
+#endif /* __LINUX_SOC_EXYNOS_ASV_H */
index c55a47c..b89c26a 100644 (file)
@@ -45,17 +45,25 @@ static const char * __init product_id_to_soc_id(unsigned int product_id)
        return NULL;
 }
 
-int __init exynos_chipid_early_init(void)
+static int __init exynos_chipid_early_init(void)
 {
        struct soc_device_attribute *soc_dev_attr;
        struct soc_device *soc_dev;
        struct device_node *root;
+       struct device_node *syscon;
        struct regmap *regmap;
        u32 product_id;
        u32 revision;
        int ret;
 
-       regmap = syscon_regmap_lookup_by_compatible("samsung,exynos4210-chipid");
+       syscon = of_find_compatible_node(NULL, NULL,
+                                        "samsung,exynos4210-chipid");
+       if (!syscon)
+               return ENODEV;
+
+       regmap = device_node_to_regmap(syscon);
+       of_node_put(syscon);
+
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
diff --git a/drivers/soc/samsung/exynos5422-asv.c b/drivers/soc/samsung/exynos5422-asv.c
new file mode 100644 (file)
index 0000000..01bb305
--- /dev/null
@@ -0,0 +1,505 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#include <linux/bitrev.h>
+#include <linux/errno.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+#include <linux/slab.h>
+
+#include "exynos-asv.h"
+#include "exynos5422-asv.h"
+
+#define ASV_GROUPS_NUM         14
+#define ASV_ARM_DVFS_NUM       20
+#define ASV_ARM_BIN2_DVFS_NUM  17
+#define ASV_KFC_DVFS_NUM       14
+#define ASV_KFC_BIN2_DVFS_NUM  12
+
+/*
+ * This array is a set of 4 ASV data tables, first column of each ASV table
+ * contains frequency value in MHz and subsequent columns contain the CPU
+ * cluster's supply voltage values in uV.
+ * In order to create a set of OPPs for specific SoC revision one of the voltage
+ * columns (1...14) from one of the tables (0...3) is selected during
+ * initialization. There are separate ASV tables for the big (ARM) and little
+ * (KFC) CPU cluster. Only OPPs which are already defined in devicetree
+ * will be updated.
+ */
+
+static const u32 asv_arm_table[][ASV_ARM_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+       /* ARM 0, 1 */
+       { 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+         1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+       { 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+         1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1900,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+         1162500, 1150000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+       { 1800,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+         1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+       { 1700,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+         1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+       { 1600,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+         1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+       { 1500,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+         1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+       { 1400,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+         975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+       { 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+         962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+       { 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+         937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+       { 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+         912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+       /* ARM 2 */
+       { 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+         1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+       { 2000,    1312500, 1312500, 1312500, 1300000, 1275000, 1262500, 1250000,
+         1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1900,    1262500, 1250000, 1250000, 1237500, 1212500, 1200000, 1187500,
+         1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+       { 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+         1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+       { 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+         1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+       { 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+         1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+       { 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+         1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+       { 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+         987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+       { 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+         962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+       { 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+         937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+       { 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+         912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+       /* ARM 3 */
+       { 2100,    1362500, 1362500, 1350000, 1337500, 1325000, 1312500, 1300000,
+         1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000 },
+       { 2000,    1312500, 1312500, 1300000, 1287500, 1275000, 1262500, 1250000,
+         1237500, 1225000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1900,    1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500,
+         1175000, 1162500, 1175000, 1162500, 1150000, 1137500, 1125000 },
+       { 1800,    1212500, 1200000, 1187500, 1175000, 1162500, 1150000, 1137500,
+         1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000 },
+       { 1700,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+         1087500, 1075000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+       { 1600,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+         1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+       { 1500,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+         1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+       { 1400,    1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000,
+         987500,  975000,  987500,  975000,  962500,  950000,  937500 },
+       { 1300,    1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+         962500,  950000,  962500,  950000,  937500,  925000,  912500 },
+       { 1200,    1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+         937500,  925000,  937500,  925000,  912500,  900000,  900000 },
+       { 1100,    1000000, 987500,  975000,  962500,  950000,  937500,  925000,
+         912500,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 1000,    975000,  962500,  950000,  937500,  925000,  912500,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 900,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 800,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 700,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+       /* ARM bin 2 */
+       { 1800,    1237500, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500,
+         1150000, 1137500, 1150000, 1137500, 1125000, 1112500, 1100000 },
+       { 1700,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+         1112500, 1100000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+       { 1600,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+         1075000, 1062500, 1075000, 1062500, 1050000, 1037500, 1025000 },
+       { 1500,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+         1037500, 1025000, 1037500, 1025000, 1012500, 1000000, 987500 },
+       { 1400,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+         1012500, 1000000, 1012500, 1000000, 987500,  975000,  962500 },
+       { 1300,    1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+         1000000, 987500,  1000000, 987500,  975000,  962500,  950000 },
+       { 1200,    1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+         975000,  962500,  975000,  962500,  950000,  937500,  925000 },
+       { 1100,    1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500,
+         950000,  937500,  950000,  937500,  925000,  912500,  900000 },
+       { 1000,    1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+         925000,  912500,  925000,  912500,  900000,  900000,  900000 },
+       { 900,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 800,     962500,  950000,  937500,  925000,  912500,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 700,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 600,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const u32 asv_kfc_table[][ASV_KFC_DVFS_NUM][ASV_GROUPS_NUM + 1] = {
+{
+       /* KFC 0, 1 */
+       { 1500000, 1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+         1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1400000, 1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+         1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+       { 1300000, 1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+         1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+       { 1200000, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+         1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+       { 1100000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+         1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+       { 1000000, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+         1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+       { 900000,  1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+         975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+       { 800000,  1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+         937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+       { 700000,  987500,  975000,  962500,  950000,  937500,  925000,  912500,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 600000,  950000,  937500,  925000,  912500,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500000,  912500,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200000,  900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+       /* KFC 2 */
+       { 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+         1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+         1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+       { 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+         1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+       { 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+         1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+       { 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+         1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+       { 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+         1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+       { 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+         975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+       { 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+         937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+       { 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+       /* KFC 3 */
+       { 1500,    1300000, 1300000, 1300000, 1287500, 1287500, 1287500, 1275000,
+         1262500, 1250000, 1237500, 1225000, 1212500, 1200000, 1187500 },
+       { 1400,    1275000, 1262500, 1250000, 1237500, 1225000, 1212500, 1200000,
+         1187500, 1175000, 1162500, 1150000, 1137500, 1125000, 1112500 },
+       { 1300,    1225000, 1212500, 1200000, 1187500, 1175000, 1162500, 1150000,
+         1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 },
+       { 1200,    1175000, 1162500, 1150000, 1137500, 1125000, 1112500, 1100000,
+         1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500 },
+       { 1100,    1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500,
+         1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000 },
+       { 1000,    1100000, 1087500, 1075000, 1062500, 1050000, 1037500, 1025000,
+         1012500, 1000000, 987500,  975000,  962500,  950000,  937500 },
+       { 900,     1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500,
+         975000,  962500,  950000,  937500,  925000,  912500,  900000 },
+       { 800,     1025000, 1012500, 1000000, 987500,  975000,  962500,  950000,
+         937500,  925000,  912500,  900000,  900000,  900000,  900000 },
+       { 700,     987500,  975000,  962500,  950000,  937500,  925000,  912500,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 600,     950000,  937500,  925000,  912500,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500,     912500,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}, {
+       /* KFC bin 2 */
+       { 1300,    1250000, 1237500, 1225000, 1212500, 1200000, 1187500, 1175000,
+         1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500 },
+       { 1200,    1200000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000,
+         1112500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 },
+       { 1100,    1162500, 1150000, 1137500, 1125000, 1112500, 1100000, 1087500,
+         1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000 },
+       { 1000,    1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1050000,
+         1037500, 1025000, 1012500, 1000000, 987500,  975000,  962500 },
+       { 900,     1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500,
+         1000000, 987500,  975000,  962500,  950000,  937500,  925000 },
+       { 800,     1050000, 1037500, 1025000, 1012500, 1000000, 987500,  975000,
+         962500,  950000,  937500,  925000,  912500,  900000,  900000 },
+       { 700,     1012500, 1000000, 987500,  975000,  962500,  950000,  937500,
+         925000,  912500,  900000,  900000,  900000,  900000,  900000 },
+       { 600,     975000,  962500,  950000,  937500,  925000,  912500,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 500,     937500,  925000,  912500,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 400,     925000,  912500,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 300,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+       { 200,     900000,  900000,  900000,  900000,  900000,  900000,  900000,
+         900000,  900000,  900000,  900000,  900000,  900000,  900000 },
+}
+};
+
+static const struct asv_limit_entry __asv_limits[ASV_GROUPS_NUM] = {
+       { 13, 55 },
+       { 21, 65 },
+       { 25, 69 },
+       { 30, 72 },
+       { 36, 74 },
+       { 43, 76 },
+       { 51, 78 },
+       { 65, 80 },
+       { 81, 82 },
+       { 98, 84 },
+       { 119, 87 },
+       { 135, 89 },
+       { 150, 92 },
+       { 999, 999 },
+};
+
+static int exynos5422_asv_get_group(struct exynos_asv *asv)
+{
+       unsigned int pkgid_reg, auxi_reg;
+       int hpm, ids, i;
+
+       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkgid_reg);
+       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &auxi_reg);
+
+       if (asv->use_sg) {
+               u32 sga = (pkgid_reg >> EXYNOS5422_SG_A_OFFSET) &
+                          EXYNOS5422_SG_A_MASK;
+
+               u32 sgb = (pkgid_reg >> EXYNOS5422_SG_B_OFFSET) &
+                          EXYNOS5422_SG_B_MASK;
+
+               if ((pkgid_reg >> EXYNOS5422_SG_BSIGN_OFFSET) &
+                    EXYNOS5422_SG_BSIGN_MASK)
+                       return sga + sgb;
+               else
+                       return sga - sgb;
+       }
+
+       hpm = (auxi_reg >> EXYNOS5422_TMCB_OFFSET) & EXYNOS5422_TMCB_MASK;
+       ids = (pkgid_reg >> EXYNOS5422_IDS_OFFSET) & EXYNOS5422_IDS_MASK;
+
+       for (i = 0; i < ASV_GROUPS_NUM; i++) {
+               if (ids <= __asv_limits[i].ids)
+                       break;
+               if (hpm <= __asv_limits[i].hpm)
+                       break;
+       }
+       if (i < ASV_GROUPS_NUM)
+               return i;
+
+       return 0;
+}
+
+static int __asv_offset_voltage(unsigned int index)
+{
+       switch (index) {
+       case 1:
+               return 12500;
+       case 2:
+               return 50000;
+       case 3:
+               return 25000;
+       default:
+               return 0;
+       };
+}
+
+static void exynos5422_asv_offset_voltage_setup(struct exynos_asv *asv)
+{
+       struct exynos_asv_subsys *subsys;
+       unsigned int reg, value;
+
+       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_AUX_INFO, &reg);
+
+       /* ARM offset voltage setup */
+       subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+
+       subsys->base_volt = 1000000;
+
+       value = (reg >> EXYNOS5422_ARM_UP_OFFSET) & EXYNOS5422_ARM_UP_MASK;
+       subsys->offset_volt_h = __asv_offset_voltage(value);
+
+       value = (reg >> EXYNOS5422_ARM_DN_OFFSET) & EXYNOS5422_ARM_DN_MASK;
+       subsys->offset_volt_l = __asv_offset_voltage(value);
+
+       /* KFC offset voltage setup */
+       subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+
+       subsys->base_volt = 1000000;
+
+       value = (reg >> EXYNOS5422_KFC_UP_OFFSET) & EXYNOS5422_KFC_UP_MASK;
+       subsys->offset_volt_h = __asv_offset_voltage(value);
+
+       value = (reg >> EXYNOS5422_KFC_DN_OFFSET) & EXYNOS5422_KFC_DN_MASK;
+       subsys->offset_volt_l = __asv_offset_voltage(value);
+}
+
+static int exynos5422_asv_opp_get_voltage(const struct exynos_asv_subsys *subsys,
+                                         int level, unsigned int volt)
+{
+       unsigned int asv_volt;
+
+       if (level >= subsys->table.num_rows)
+               return volt;
+
+       asv_volt = exynos_asv_opp_get_voltage(subsys, level,
+                                             subsys->asv->group);
+
+       if (volt > subsys->base_volt)
+               asv_volt += subsys->offset_volt_h;
+       else
+               asv_volt += subsys->offset_volt_l;
+
+       return asv_volt;
+}
+
+static unsigned int exynos5422_asv_parse_table(unsigned int pkg_id)
+{
+       return (pkg_id >> EXYNOS5422_TABLE_OFFSET) & EXYNOS5422_TABLE_MASK;
+}
+
+static bool exynos5422_asv_parse_bin2(unsigned int pkg_id)
+{
+       return (pkg_id >> EXYNOS5422_BIN2_OFFSET) & EXYNOS5422_BIN2_MASK;
+}
+
+static bool exynos5422_asv_parse_sg(unsigned int pkg_id)
+{
+       return (pkg_id >> EXYNOS5422_USESG_OFFSET) & EXYNOS5422_USESG_MASK;
+}
+
+int exynos5422_asv_init(struct exynos_asv *asv)
+{
+       struct exynos_asv_subsys *subsys;
+       unsigned int table_index;
+       unsigned int pkg_id;
+       bool bin2;
+
+       regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PKG_ID, &pkg_id);
+
+       if (asv->of_bin == 2) {
+               bin2 = true;
+               asv->use_sg = false;
+       } else {
+               asv->use_sg = exynos5422_asv_parse_sg(pkg_id);
+               bin2 = exynos5422_asv_parse_bin2(pkg_id);
+       }
+
+       asv->group = exynos5422_asv_get_group(asv);
+       asv->table = exynos5422_asv_parse_table(pkg_id);
+
+       exynos5422_asv_offset_voltage_setup(asv);
+
+       if (bin2) {
+               table_index = 3;
+       } else {
+               if (asv->table == 2 || asv->table == 3)
+                       table_index = asv->table - 1;
+               else
+                       table_index = 0;
+       }
+
+       subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_ARM];
+       subsys->cpu_dt_compat = "arm,cortex-a15";
+       if (bin2)
+               subsys->table.num_rows = ASV_ARM_BIN2_DVFS_NUM;
+       else
+               subsys->table.num_rows = ASV_ARM_DVFS_NUM;
+       subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+       subsys->table.buf = (u32 *)asv_arm_table[table_index];
+
+       subsys = &asv->subsys[EXYNOS_ASV_SUBSYS_ID_KFC];
+       subsys->cpu_dt_compat = "arm,cortex-a7";
+       if (bin2)
+               subsys->table.num_rows = ASV_KFC_BIN2_DVFS_NUM;
+       else
+               subsys->table.num_rows = ASV_KFC_DVFS_NUM;
+       subsys->table.num_cols = ASV_GROUPS_NUM + 1;
+       subsys->table.buf = (u32 *)asv_kfc_table[table_index];
+
+       asv->opp_get_voltage = exynos5422_asv_opp_get_voltage;
+
+       return 0;
+}
diff --git a/drivers/soc/samsung/exynos5422-asv.h b/drivers/soc/samsung/exynos5422-asv.h
new file mode 100644 (file)
index 0000000..95a5fb1
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * Samsung Exynos 5422 SoC Adaptive Supply Voltage support
+ */
+
+#ifndef __LINUX_SOC_EXYNOS5422_ASV_H
+#define __LINUX_SOC_EXYNOS5422_ASV_H
+
+#include <linux/errno.h>
+
+enum {
+       EXYNOS_ASV_SUBSYS_ID_ARM,
+       EXYNOS_ASV_SUBSYS_ID_KFC,
+       EXYNOS_ASV_SUBSYS_ID_MAX
+};
+
+struct exynos_asv;
+
+#ifdef CONFIG_EXYNOS_ASV_ARM
+int exynos5422_asv_init(struct exynos_asv *asv);
+#else
+static inline int exynos5422_asv_init(struct exynos_asv *asv)
+{
+       return -ENOTSUPP;
+}
+#endif
+
+#endif /* __LINUX_SOC_EXYNOS5422_ASV_H */
index c8ef05d..84bd615 100644 (file)
@@ -15,6 +15,7 @@ config ARCH_TEGRA_2x_SOC
        select PL310_ERRATA_769419 if CACHE_L2X0
        select SOC_TEGRA_FLOWCTRL
        select SOC_TEGRA_PMC
+       select SOC_TEGRA20_VOLTAGE_COUPLER
        select TEGRA_TIMER
        help
          Support for NVIDIA Tegra AP20 and T20 processors, based on the
@@ -28,6 +29,7 @@ config ARCH_TEGRA_3x_SOC
        select PL310_ERRATA_769419 if CACHE_L2X0
        select SOC_TEGRA_FLOWCTRL
        select SOC_TEGRA_PMC
+       select SOC_TEGRA30_VOLTAGE_COUPLER
        select TEGRA_TIMER
        help
          Support for NVIDIA Tegra T30 processor family, based on the
@@ -135,3 +137,11 @@ config SOC_TEGRA_POWERGATE_BPMP
        def_bool y
        depends on PM_GENERIC_DOMAINS
        depends on TEGRA_BPMP
+
+config SOC_TEGRA20_VOLTAGE_COUPLER
+       bool "Voltage scaling support for Tegra20 SoCs"
+       depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
+
+config SOC_TEGRA30_VOLTAGE_COUPLER
+       bool "Voltage scaling support for Tegra30 SoCs"
+       depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST
index 902759f..9c809c1 100644 (file)
@@ -5,3 +5,5 @@ obj-y += common.o
 obj-$(CONFIG_SOC_TEGRA_FLOWCTRL) += flowctrl.o
 obj-$(CONFIG_SOC_TEGRA_PMC) += pmc.o
 obj-$(CONFIG_SOC_TEGRA_POWERGATE_BPMP) += powergate-bpmp.o
+obj-$(CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER) += regulators-tegra20.o
+obj-$(CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER) += regulators-tegra30.o
index b6bdeef..eb96a30 100644 (file)
@@ -91,8 +91,23 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
                reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
                /* clear wfi bitmap */
                reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
-               /* pwr gating on wfi */
-               reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
+
+               if (tegra_get_chip_id() == TEGRA30) {
+                       /*
+                        * The wfi doesn't work well on Tegra30 because
+                        * CPU hangs under some odd circumstances after
+                        * power-gating (like memory running off PLLP),
+                        * hence use wfe that is working perfectly fine.
+                        * Note that Tegra30 TRM doc clearly stands that
+                        * wfi should be used for the "Cluster Switching",
+                        * while wfe for the power-gating, just like it
+                        * is done on Tegra20.
+                        */
+                       reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
+               } else {
+                       /* pwr gating on wfi */
+                       reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
+               }
                break;
        }
        reg |= FLOW_CTRL_CSR_INTR_FLAG;                 /* clear intr flag */
index 3eb44e6..4d719d4 100644 (file)
@@ -8,6 +8,8 @@
 #include <linux/kobject.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/nvmem-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
@@ -31,50 +33,6 @@ static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
        [TEGRA_REVISION_A04]     = "A04",
 };
 
-static u8 fuse_readb(struct tegra_fuse *fuse, unsigned int offset)
-{
-       u32 val;
-
-       val = fuse->read(fuse, round_down(offset, 4));
-       val >>= (offset % 4) * 8;
-       val &= 0xff;
-
-       return val;
-}
-
-static ssize_t fuse_read(struct file *fd, struct kobject *kobj,
-                        struct bin_attribute *attr, char *buf,
-                        loff_t pos, size_t size)
-{
-       struct device *dev = kobj_to_dev(kobj);
-       struct tegra_fuse *fuse = dev_get_drvdata(dev);
-       int i;
-
-       if (pos < 0 || pos >= attr->size)
-               return 0;
-
-       if (size > attr->size - pos)
-               size = attr->size - pos;
-
-       for (i = 0; i < size; i++)
-               buf[i] = fuse_readb(fuse, pos + i);
-
-       return i;
-}
-
-static struct bin_attribute fuse_bin_attr = {
-       .attr = { .name = "fuse", .mode = S_IRUGO, },
-       .read = fuse_read,
-};
-
-static int tegra_fuse_create_sysfs(struct device *dev, unsigned int size,
-                                  const struct tegra_fuse_info *info)
-{
-       fuse_bin_attr.size = size;
-
-       return device_create_bin_file(dev, &fuse_bin_attr);
-}
-
 static const struct of_device_id car_match[] __initconst = {
        { .compatible = "nvidia,tegra20-car", },
        { .compatible = "nvidia,tegra30-car", },
@@ -115,9 +73,111 @@ static const struct of_device_id tegra_fuse_match[] = {
        { /* sentinel */ }
 };
 
+static int tegra_fuse_read(void *priv, unsigned int offset, void *value,
+                          size_t bytes)
+{
+       unsigned int count = bytes / 4, i;
+       struct tegra_fuse *fuse = priv;
+       u32 *buffer = value;
+
+       for (i = 0; i < count; i++)
+               buffer[i] = fuse->read(fuse, offset + i * 4);
+
+       return 0;
+}
+
+static const struct nvmem_cell_info tegra_fuse_cells[] = {
+       {
+               .name = "tsensor-cpu1",
+               .offset = 0x084,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-cpu2",
+               .offset = 0x088,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-cpu0",
+               .offset = 0x098,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "xusb-pad-calibration",
+               .offset = 0x0f0,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-cpu3",
+               .offset = 0x12c,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "sata-calibration",
+               .offset = 0x124,
+               .bytes = 1,
+               .bit_offset = 0,
+               .nbits = 2,
+       }, {
+               .name = "tsensor-gpu",
+               .offset = 0x154,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-mem0",
+               .offset = 0x158,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-mem1",
+               .offset = 0x15c,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-pllx",
+               .offset = 0x160,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-common",
+               .offset = 0x180,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "tsensor-realignment",
+               .offset = 0x1fc,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "gpu-calibration",
+               .offset = 0x204,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       }, {
+               .name = "xusb-pad-calibration-ext",
+               .offset = 0x250,
+               .bytes = 4,
+               .bit_offset = 0,
+               .nbits = 32,
+       },
+};
+
 static int tegra_fuse_probe(struct platform_device *pdev)
 {
        void __iomem *base = fuse->base;
+       struct nvmem_config nvmem;
        struct resource *res;
        int err;
 
@@ -146,20 +206,42 @@ static int tegra_fuse_probe(struct platform_device *pdev)
 
        if (fuse->soc->probe) {
                err = fuse->soc->probe(fuse);
-               if (err < 0) {
-                       fuse->base = base;
-                       return err;
-               }
+               if (err < 0)
+                       goto restore;
        }
 
-       if (tegra_fuse_create_sysfs(&pdev->dev, fuse->soc->info->size,
-                                   fuse->soc->info))
-               return -ENODEV;
+       memset(&nvmem, 0, sizeof(nvmem));
+       nvmem.dev = &pdev->dev;
+       nvmem.name = "fuse";
+       nvmem.id = -1;
+       nvmem.owner = THIS_MODULE;
+       nvmem.cells = tegra_fuse_cells;
+       nvmem.ncells = ARRAY_SIZE(tegra_fuse_cells);
+       nvmem.type = NVMEM_TYPE_OTP;
+       nvmem.read_only = true;
+       nvmem.root_only = true;
+       nvmem.reg_read = tegra_fuse_read;
+       nvmem.size = fuse->soc->info->size;
+       nvmem.word_size = 4;
+       nvmem.stride = 4;
+       nvmem.priv = fuse;
+
+       fuse->nvmem = devm_nvmem_register(&pdev->dev, &nvmem);
+       if (IS_ERR(fuse->nvmem)) {
+               err = PTR_ERR(fuse->nvmem);
+               dev_err(&pdev->dev, "failed to register NVMEM device: %d\n",
+                       err);
+               goto restore;
+       }
 
        /* release the early I/O memory mapping */
        iounmap(base);
 
        return 0;
+
+restore:
+       fuse->base = base;
+       return err;
 }
 
 static struct platform_driver tegra_fuse_driver = {
@@ -186,9 +268,12 @@ u32 __init tegra_fuse_read_early(unsigned int offset)
 
 int tegra_fuse_readl(unsigned long offset, u32 *value)
 {
-       if (!fuse->read)
+       if (!fuse->read || !fuse->clk)
                return -EPROBE_DEFER;
 
+       if (IS_ERR(fuse->clk))
+               return PTR_ERR(fuse->clk);
+
        *value = fuse->read(fuse, offset);
 
        return 0;
@@ -338,6 +423,15 @@ static int __init tegra_init_fuse(void)
        pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
                 tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
 
+       if (fuse->soc->lookups) {
+               size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups;
+
+               fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL);
+               if (!fuse->lookups)
+                       return -ENOMEM;
+
+               nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
+       }
 
        return 0;
 }
index be9424a..b8daaf5 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
@@ -127,6 +128,70 @@ const struct tegra_fuse_soc tegra114_fuse_soc = {
 #endif
 
 #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
+static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = {
+       {
+               .nvmem_name = "fuse",
+               .cell_name = "xusb-pad-calibration",
+               .dev_id = "7009f000.padctl",
+               .con_id = "calibration",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "sata-calibration",
+               .dev_id = "70020000.sata",
+               .con_id = "calibration",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-common",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "common",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-realignment",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "realignment",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu0",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu0",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu1",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu1",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu2",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu2",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu3",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu3",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-mem0",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "mem0",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-mem1",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "mem1",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-gpu",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "gpu",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-pllx",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "pllx",
+       },
+};
+
 static const struct tegra_fuse_info tegra124_fuse_info = {
        .read = tegra30_fuse_read,
        .size = 0x300,
@@ -137,10 +202,81 @@ const struct tegra_fuse_soc tegra124_fuse_soc = {
        .init = tegra30_fuse_init,
        .speedo_init = tegra124_init_speedo_data,
        .info = &tegra124_fuse_info,
+       .lookups = tegra124_fuse_lookups,
+       .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
 };
 #endif
 
 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
+static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = {
+       {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu1",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu1",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu2",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu2",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu0",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu0",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "xusb-pad-calibration",
+               .dev_id = "7009f000.padctl",
+               .con_id = "calibration",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-cpu3",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "cpu3",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "sata-calibration",
+               .dev_id = "70020000.sata",
+               .con_id = "calibration",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-gpu",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "gpu",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-mem0",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "mem0",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-mem1",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "mem1",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-pllx",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "pllx",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "tsensor-common",
+               .dev_id = "700e2000.thermal-sensor",
+               .con_id = "common",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "gpu-calibration",
+               .dev_id = "57000000.gpu",
+               .con_id = "calibration",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "xusb-pad-calibration-ext",
+               .dev_id = "7009f000.padctl",
+               .con_id = "calibration-ext",
+       },
+};
+
 static const struct tegra_fuse_info tegra210_fuse_info = {
        .read = tegra30_fuse_read,
        .size = 0x300,
@@ -151,10 +287,26 @@ const struct tegra_fuse_soc tegra210_fuse_soc = {
        .init = tegra30_fuse_init,
        .speedo_init = tegra210_init_speedo_data,
        .info = &tegra210_fuse_info,
+       .lookups = tegra210_fuse_lookups,
+       .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
 };
 #endif
 
 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
+static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = {
+       {
+               .nvmem_name = "fuse",
+               .cell_name = "xusb-pad-calibration",
+               .dev_id = "3520000.padctl",
+               .con_id = "calibration",
+       }, {
+               .nvmem_name = "fuse",
+               .cell_name = "xusb-pad-calibration-ext",
+               .dev_id = "3520000.padctl",
+               .con_id = "calibration-ext",
+       },
+};
+
 static const struct tegra_fuse_info tegra186_fuse_info = {
        .read = tegra30_fuse_read,
        .size = 0x300,
@@ -164,5 +316,7 @@ static const struct tegra_fuse_info tegra186_fuse_info = {
 const struct tegra_fuse_soc tegra186_fuse_soc = {
        .init = tegra30_fuse_init,
        .info = &tegra186_fuse_info,
+       .lookups = tegra186_fuse_lookups,
+       .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
 };
 #endif
index 7230cb3..0f74c2c 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/dmaengine.h>
 #include <linux/types.h>
 
+struct nvmem_cell_lookup;
+struct nvmem_device;
 struct tegra_fuse;
 
 struct tegra_fuse_info {
@@ -27,6 +29,9 @@ struct tegra_fuse_soc {
        int (*probe)(struct tegra_fuse *fuse);
 
        const struct tegra_fuse_info *info;
+
+       const struct nvmem_cell_lookup *lookups;
+       unsigned int num_lookups;
 };
 
 struct tegra_fuse {
@@ -48,6 +53,9 @@ struct tegra_fuse {
                dma_addr_t phys;
                u32 *virt;
        } apbdma;
+
+       struct nvmem_device *nvmem;
+       struct nvmem_cell_lookup *lookups;
 };
 
 void tegra_init_revision(void);
index 9f9c1c6..ea0e11a 100644 (file)
 #define  PMC_CNTRL_SIDE_EFFECT_LP0     BIT(14) /* LP0 when CPU pwr gated */
 #define  PMC_CNTRL_SYSCLK_OE           BIT(11) /* system clock enable */
 #define  PMC_CNTRL_SYSCLK_POLARITY     BIT(10) /* sys clk polarity */
+#define  PMC_CNTRL_PWRREQ_POLARITY     BIT(8)
 #define  PMC_CNTRL_MAIN_RST            BIT(4)
 
+#define PMC_WAKE_MASK                  0x0c
+#define PMC_WAKE_LEVEL                 0x10
+#define PMC_WAKE_STATUS                        0x14
+#define PMC_SW_WAKE_STATUS             0x18
+
 #define DPD_SAMPLE                     0x020
 #define  DPD_SAMPLE_ENABLE             BIT(0)
 #define  DPD_SAMPLE_DISABLE            (0 << 0)
 
 #define PMC_CPUPWRGOOD_TIMER           0xc8
 #define PMC_CPUPWROFF_TIMER            0xcc
+#define PMC_COREPWRGOOD_TIMER          0x3c
+#define PMC_COREPWROFF_TIMER           0xe0
 
 #define PMC_PWR_DET_VALUE              0xe4
 
 #define PMC_SCRATCH41                  0x140
 
+#define PMC_WAKE2_MASK                 0x160
+#define PMC_WAKE2_LEVEL                        0x164
+#define PMC_WAKE2_STATUS               0x168
+#define PMC_SW_WAKE2_STATUS            0x16c
+
 #define PMC_SENSOR_CTRL                        0x1b0
 #define  PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
 #define  PMC_SENSOR_CTRL_ENABLE_RST    BIT(1)
@@ -226,6 +239,8 @@ struct tegra_pmc_soc {
        void (*setup_irq_polarity)(struct tegra_pmc *pmc,
                                   struct device_node *np,
                                   bool invert);
+       int (*irq_set_wake)(struct irq_data *data, unsigned int on);
+       int (*irq_set_type)(struct irq_data *data, unsigned int type);
 
        const char * const *reset_sources;
        unsigned int num_reset_sources;
@@ -309,6 +324,7 @@ static const char * const tegra210_reset_sources[] = {
  * @pctl_dev: pin controller exposed by the PMC
  * @domain: IRQ domain provided by the PMC
  * @irq: chip implementation for the IRQ domain
+ * @clk_nb: pclk clock changes handler
  */
 struct tegra_pmc {
        struct device *dev;
@@ -344,6 +360,8 @@ struct tegra_pmc {
 
        struct irq_domain *domain;
        struct irq_chip irq;
+
+       struct notifier_block clk_nb;
 };
 
 static struct tegra_pmc *pmc = &(struct tegra_pmc) {
@@ -1192,7 +1210,7 @@ static int tegra_io_pad_prepare(struct tegra_pmc *pmc, enum tegra_io_pad id,
                return err;
 
        if (pmc->clk) {
-               rate = clk_get_rate(pmc->clk);
+               rate = pmc->rate;
                if (!rate) {
                        dev_err(pmc->dev, "failed to get clock rate\n");
                        return -ENODEV;
@@ -1433,6 +1451,7 @@ void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode)
 void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
 {
        unsigned long long rate = 0;
+       u64 ticks;
        u32 value;
 
        switch (mode) {
@@ -1441,7 +1460,7 @@ void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
                break;
 
        case TEGRA_SUSPEND_LP2:
-               rate = clk_get_rate(pmc->clk);
+               rate = pmc->rate;
                break;
 
        default:
@@ -1451,21 +1470,13 @@ void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
        if (WARN_ON_ONCE(rate == 0))
                rate = 100000000;
 
-       if (rate != pmc->rate) {
-               u64 ticks;
-
-               ticks = pmc->cpu_good_time * rate + USEC_PER_SEC - 1;
-               do_div(ticks, USEC_PER_SEC);
-               tegra_pmc_writel(pmc, ticks, PMC_CPUPWRGOOD_TIMER);
+       ticks = pmc->cpu_good_time * rate + USEC_PER_SEC - 1;
+       do_div(ticks, USEC_PER_SEC);
+       tegra_pmc_writel(pmc, ticks, PMC_CPUPWRGOOD_TIMER);
 
-               ticks = pmc->cpu_off_time * rate + USEC_PER_SEC - 1;
-               do_div(ticks, USEC_PER_SEC);
-               tegra_pmc_writel(pmc, ticks, PMC_CPUPWROFF_TIMER);
-
-               wmb();
-
-               pmc->rate = rate;
-       }
+       ticks = pmc->cpu_off_time * rate + USEC_PER_SEC - 1;
+       do_div(ticks, USEC_PER_SEC);
+       tegra_pmc_writel(pmc, ticks, PMC_CPUPWROFF_TIMER);
 
        value = tegra_pmc_readl(pmc, PMC_CNTRL);
        value &= ~PMC_CNTRL_SIDE_EFFECT_LP0;
@@ -1899,6 +1910,20 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
                                                            event->id,
                                                            &pmc->irq, pmc);
 
+                       /*
+                        * GPIOs don't have an equivalent interrupt in the
+                        * parent controller (GIC). However some code, such
+                        * as the one in irq_get_irqchip_state(), require a
+                        * valid IRQ chip to be set. Make sure that's the
+                        * case by passing NULL here, which will install a
+                        * dummy IRQ chip for the interrupt in the parent
+                        * domain.
+                        */
+                       if (domain->parent)
+                               irq_domain_set_hwirq_and_chip(domain->parent,
+                                                             virq, 0, NULL,
+                                                             NULL);
+
                        break;
                }
        }
@@ -1908,10 +1933,22 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
         * dummy hardware IRQ number. This is used in the ->irq_set_type()
         * and ->irq_set_wake() callbacks to return early for these IRQs.
         */
-       if (i == soc->num_wake_events)
+       if (i == soc->num_wake_events) {
                err = irq_domain_set_hwirq_and_chip(domain, virq, ULONG_MAX,
                                                    &pmc->irq, pmc);
 
+               /*
+                * Interrupts without a wake event don't have a corresponding
+                * interrupt in the parent controller (GIC). Pass NULL for the
+                * chip here, which causes a dummy IRQ chip to be installed
+                * for the interrupt in the parent domain, to make this
+                * explicit.
+                */
+               if (domain->parent)
+                       irq_domain_set_hwirq_and_chip(domain->parent, virq, 0,
+                                                     NULL, NULL);
+       }
+
        return err;
 }
 
@@ -1920,7 +1957,87 @@ static const struct irq_domain_ops tegra_pmc_irq_domain_ops = {
        .alloc = tegra_pmc_irq_alloc,
 };
 
-static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
+static int tegra210_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+       struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
+       unsigned int offset, bit;
+       u32 value;
+
+       if (data->hwirq == ULONG_MAX)
+               return 0;
+
+       offset = data->hwirq / 32;
+       bit = data->hwirq % 32;
+
+       /* clear wake status */
+       tegra_pmc_writel(pmc, 0, PMC_SW_WAKE_STATUS);
+       tegra_pmc_writel(pmc, 0, PMC_SW_WAKE2_STATUS);
+
+       tegra_pmc_writel(pmc, 0, PMC_WAKE_STATUS);
+       tegra_pmc_writel(pmc, 0, PMC_WAKE2_STATUS);
+
+       /* enable PMC wake */
+       if (data->hwirq >= 32)
+               offset = PMC_WAKE2_MASK;
+       else
+               offset = PMC_WAKE_MASK;
+
+       value = tegra_pmc_readl(pmc, offset);
+
+       if (on)
+               value |= BIT(bit);
+       else
+               value &= ~BIT(bit);
+
+       tegra_pmc_writel(pmc, value, offset);
+
+       return 0;
+}
+
+static int tegra210_pmc_irq_set_type(struct irq_data *data, unsigned int type)
+{
+       struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
+       unsigned int offset, bit;
+       u32 value;
+
+       if (data->hwirq == ULONG_MAX)
+               return 0;
+
+       offset = data->hwirq / 32;
+       bit = data->hwirq % 32;
+
+       if (data->hwirq >= 32)
+               offset = PMC_WAKE2_LEVEL;
+       else
+               offset = PMC_WAKE_LEVEL;
+
+       value = tegra_pmc_readl(pmc, offset);
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+       case IRQ_TYPE_LEVEL_HIGH:
+               value |= BIT(bit);
+               break;
+
+       case IRQ_TYPE_EDGE_FALLING:
+       case IRQ_TYPE_LEVEL_LOW:
+               value &= ~BIT(bit);
+               break;
+
+       case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING:
+               value ^= BIT(bit);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       tegra_pmc_writel(pmc, value, offset);
+
+       return 0;
+}
+
+static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
 {
        struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
        unsigned int offset, bit;
@@ -1952,7 +2069,7 @@ static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
        return 0;
 }
 
-static int tegra_pmc_irq_set_type(struct irq_data *data, unsigned int type)
+static int tegra186_pmc_irq_set_type(struct irq_data *data, unsigned int type)
 {
        struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
        u32 value;
@@ -2006,8 +2123,8 @@ static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
        pmc->irq.irq_unmask = irq_chip_unmask_parent;
        pmc->irq.irq_eoi = irq_chip_eoi_parent;
        pmc->irq.irq_set_affinity = irq_chip_set_affinity_parent;
-       pmc->irq.irq_set_type = tegra_pmc_irq_set_type;
-       pmc->irq.irq_set_wake = tegra_pmc_irq_set_wake;
+       pmc->irq.irq_set_type = pmc->soc->irq_set_type;
+       pmc->irq.irq_set_wake = pmc->soc->irq_set_wake;
 
        pmc->domain = irq_domain_add_hierarchy(parent, 0, 96, pmc->dev->of_node,
                                               &tegra_pmc_irq_domain_ops, pmc);
@@ -2019,6 +2136,33 @@ static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
        return 0;
 }
 
+static int tegra_pmc_clk_notify_cb(struct notifier_block *nb,
+                                  unsigned long action, void *ptr)
+{
+       struct tegra_pmc *pmc = container_of(nb, struct tegra_pmc, clk_nb);
+       struct clk_notifier_data *data = ptr;
+
+       switch (action) {
+       case PRE_RATE_CHANGE:
+               mutex_lock(&pmc->powergates_lock);
+               break;
+
+       case POST_RATE_CHANGE:
+               pmc->rate = data->new_rate;
+               /* fall through */
+
+       case ABORT_RATE_CHANGE:
+               mutex_unlock(&pmc->powergates_lock);
+               break;
+
+       default:
+               WARN_ON_ONCE(1);
+               return notifier_from_errno(-EINVAL);
+       }
+
+       return NOTIFY_OK;
+}
+
 static int tegra_pmc_probe(struct platform_device *pdev)
 {
        void __iomem *base;
@@ -2082,6 +2226,23 @@ static int tegra_pmc_probe(struct platform_device *pdev)
                pmc->clk = NULL;
        }
 
+       /*
+        * PCLK clock rate can't be retrieved using CLK API because it
+        * causes lockup if CPU enters LP2 idle state from some other
+        * CLK notifier, hence we're caching the rate's value locally.
+        */
+       if (pmc->clk) {
+               pmc->clk_nb.notifier_call = tegra_pmc_clk_notify_cb;
+               err = clk_notifier_register(pmc->clk, &pmc->clk_nb);
+               if (err) {
+                       dev_err(&pdev->dev,
+                               "failed to register clk notifier\n");
+                       return err;
+               }
+
+               pmc->rate = clk_get_rate(pmc->clk);
+       }
+
        pmc->dev = &pdev->dev;
 
        tegra_pmc_init(pmc);
@@ -2133,6 +2294,8 @@ cleanup_debugfs:
 cleanup_sysfs:
        device_remove_file(&pdev->dev, &dev_attr_reset_reason);
        device_remove_file(&pdev->dev, &dev_attr_reset_level);
+       clk_notifier_unregister(pmc->clk, &pmc->clk_nb);
+
        return err;
 }
 
@@ -2184,7 +2347,7 @@ static const struct tegra_pmc_regs tegra20_pmc_regs = {
 
 static void tegra20_pmc_init(struct tegra_pmc *pmc)
 {
-       u32 value;
+       u32 value, osc, pmu, off;
 
        /* Always enable CPU power request */
        value = tegra_pmc_readl(pmc, PMC_CNTRL);
@@ -2198,6 +2361,11 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc)
        else
                value |= PMC_CNTRL_SYSCLK_POLARITY;
 
+       if (pmc->corereq_high)
+               value &= ~PMC_CNTRL_PWRREQ_POLARITY;
+       else
+               value |= PMC_CNTRL_PWRREQ_POLARITY;
+
        /* configure the output polarity while the request is tristated */
        tegra_pmc_writel(pmc, value, PMC_CNTRL);
 
@@ -2205,6 +2373,16 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc)
        value = tegra_pmc_readl(pmc, PMC_CNTRL);
        value |= PMC_CNTRL_SYSCLK_OE;
        tegra_pmc_writel(pmc, value, PMC_CNTRL);
+
+       /* program core timings which are applicable only for suspend state */
+       if (pmc->suspend_mode != TEGRA_SUSPEND_NONE) {
+               osc = DIV_ROUND_UP(pmc->core_osc_time * 8192, 1000000);
+               pmu = DIV_ROUND_UP(pmc->core_pmu_time * 32768, 1000000);
+               off = DIV_ROUND_UP(pmc->core_off_time * 32768, 1000000);
+               tegra_pmc_writel(pmc, ((osc << 8) & 0xff00) | (pmu & 0xff),
+                                PMC_COREPWRGOOD_TIMER);
+               tegra_pmc_writel(pmc, off, PMC_COREPWROFF_TIMER);
+       }
 }
 
 static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
@@ -2538,6 +2716,10 @@ static const struct pinctrl_pin_desc tegra210_pin_descs[] = {
        TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
 };
 
+static const struct tegra_wake_event tegra210_wake_events[] = {
+       TEGRA_WAKE_IRQ("rtc", 16, 2),
+};
+
 static const struct tegra_pmc_soc tegra210_pmc_soc = {
        .num_powergates = ARRAY_SIZE(tegra210_powergates),
        .powergates = tegra210_powergates,
@@ -2555,10 +2737,14 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+       .irq_set_wake = tegra210_pmc_irq_set_wake,
+       .irq_set_type = tegra210_pmc_irq_set_type,
        .reset_sources = tegra210_reset_sources,
        .num_reset_sources = ARRAY_SIZE(tegra210_reset_sources),
        .reset_levels = NULL,
        .num_reset_levels = 0,
+       .num_wake_events = ARRAY_SIZE(tegra210_wake_events),
+       .wake_events = tegra210_wake_events,
 };
 
 #define TEGRA186_IO_PAD_TABLE(_pad)                                         \
@@ -2618,7 +2804,7 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = {
        .dpd2_status = 0x80,
        .rst_status = 0x70,
        .rst_source_shift = 0x2,
-       .rst_source_mask = 0x3C,
+       .rst_source_mask = 0x3c,
        .rst_level_shift = 0x0,
        .rst_level_mask = 0x3,
 };
@@ -2680,6 +2866,8 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
        .regs = &tegra186_pmc_regs,
        .init = NULL,
        .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+       .irq_set_wake = tegra186_pmc_irq_set_wake,
+       .irq_set_type = tegra186_pmc_irq_set_type,
        .reset_sources = tegra186_reset_sources,
        .num_reset_sources = ARRAY_SIZE(tegra186_reset_sources),
        .reset_levels = tegra186_reset_levels,
@@ -2738,6 +2926,43 @@ static const struct tegra_io_pad_soc tegra194_io_pads[] = {
        { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = UINT_MAX },
 };
 
+static const struct tegra_pmc_regs tegra194_pmc_regs = {
+       .scratch0 = 0x2000,
+       .dpd_req = 0x74,
+       .dpd_status = 0x78,
+       .dpd2_req = 0x7c,
+       .dpd2_status = 0x80,
+       .rst_status = 0x70,
+       .rst_source_shift = 0x2,
+       .rst_source_mask = 0x7c,
+       .rst_level_shift = 0x0,
+       .rst_level_mask = 0x3,
+};
+
+static const char * const tegra194_reset_sources[] = {
+       "SYS_RESET_N",
+       "AOWDT",
+       "BCCPLEXWDT",
+       "BPMPWDT",
+       "SCEWDT",
+       "SPEWDT",
+       "APEWDT",
+       "LCCPLEXWDT",
+       "SENSOR",
+       "AOTAG",
+       "VFSENSOR",
+       "MAINSWRST",
+       "SC7",
+       "HSM",
+       "CSITE",
+       "RCEWDT",
+       "PVA0WDT",
+       "PVA1WDT",
+       "L1A_ASYNC",
+       "BPMPBOOT",
+       "FUSECRC",
+};
+
 static const struct tegra_wake_event tegra194_wake_events[] = {
        TEGRA_WAKE_GPIO("power", 29, 1, TEGRA194_AON_GPIO(EE, 4)),
        TEGRA_WAKE_IRQ("rtc", 73, 10),
@@ -2755,9 +2980,15 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
        .maybe_tz_only = false,
        .num_io_pads = ARRAY_SIZE(tegra194_io_pads),
        .io_pads = tegra194_io_pads,
-       .regs = &tegra186_pmc_regs,
+       .regs = &tegra194_pmc_regs,
        .init = NULL,
        .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+       .irq_set_wake = tegra186_pmc_irq_set_wake,
+       .irq_set_type = tegra186_pmc_irq_set_type,
+       .reset_sources = tegra194_reset_sources,
+       .num_reset_sources = ARRAY_SIZE(tegra194_reset_sources),
+       .reset_levels = tegra186_reset_levels,
+       .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
        .num_wake_events = ARRAY_SIZE(tegra194_wake_events),
        .wake_events = tegra194_wake_events,
 };
diff --git a/drivers/soc/tegra/regulators-tegra20.c b/drivers/soc/tegra/regulators-tegra20.c
new file mode 100644 (file)
index 0000000..ea0eede
--- /dev/null
@@ -0,0 +1,365 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Voltage regulators coupler for NVIDIA Tegra20
+ * Copyright (C) 2019 GRATE-DRIVER project
+ *
+ * Voltage constraints borrowed from downstream kernel sources
+ * Copyright (C) 2010-2011 NVIDIA Corporation
+ */
+
+#define pr_fmt(fmt)    "tegra voltage-coupler: " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/regulator/coupler.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+struct tegra_regulator_coupler {
+       struct regulator_coupler coupler;
+       struct regulator_dev *core_rdev;
+       struct regulator_dev *cpu_rdev;
+       struct regulator_dev *rtc_rdev;
+       int core_min_uV;
+};
+
+static inline struct tegra_regulator_coupler *
+to_tegra_coupler(struct regulator_coupler *coupler)
+{
+       return container_of(coupler, struct tegra_regulator_coupler, coupler);
+}
+
+static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
+                             struct regulator_dev *core_rdev)
+{
+       int core_min_uV = 0;
+       int core_max_uV;
+       int core_cur_uV;
+       int err;
+
+       if (tegra->core_min_uV > 0)
+               return tegra->core_min_uV;
+
+       core_cur_uV = regulator_get_voltage_rdev(core_rdev);
+       if (core_cur_uV < 0)
+               return core_cur_uV;
+
+       core_max_uV = max(core_cur_uV, 1200000);
+
+       err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+       if (err)
+               return err;
+
+       /*
+        * Limit minimum CORE voltage to a value left from bootloader or,
+        * if it's unreasonably low value, to the most common 1.2v or to
+        * whatever maximum value defined via board's device-tree.
+        */
+       tegra->core_min_uV = core_max_uV;
+
+       pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV);
+
+       return tegra->core_min_uV;
+}
+
+static int tegra20_core_rtc_max_spread(struct regulator_dev *core_rdev,
+                                      struct regulator_dev *rtc_rdev)
+{
+       struct coupling_desc *c_desc = &core_rdev->coupling_desc;
+       struct regulator_dev *rdev;
+       int max_spread;
+       unsigned int i;
+
+       for (i = 1; i < c_desc->n_coupled; i++) {
+               max_spread = core_rdev->constraints->max_spread[i - 1];
+               rdev = c_desc->coupled_rdevs[i];
+
+               if (rdev == rtc_rdev && max_spread)
+                       return max_spread;
+       }
+
+       pr_err_once("rtc-core max-spread is undefined in device-tree\n");
+
+       return 150000;
+}
+
+static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
+                                  struct regulator_dev *core_rdev,
+                                  struct regulator_dev *rtc_rdev,
+                                  int cpu_uV, int cpu_min_uV)
+{
+       int core_min_uV, core_max_uV = INT_MAX;
+       int rtc_min_uV, rtc_max_uV = INT_MAX;
+       int core_target_uV;
+       int rtc_target_uV;
+       int max_spread;
+       int core_uV;
+       int rtc_uV;
+       int err;
+
+       /*
+        * RTC and CORE voltages should be no more than 170mV from each other,
+        * CPU should be below RTC and CORE by at least 120mV. This applies
+        * to all Tegra20 SoC's.
+        */
+       max_spread = tegra20_core_rtc_max_spread(core_rdev, rtc_rdev);
+
+       /*
+        * The core voltage scaling is currently not hooked up in drivers,
+        * hence we will limit the minimum core voltage to a reasonable value.
+        * This should be good enough for the time being.
+        */
+       core_min_uV = tegra20_core_limit(tegra, core_rdev);
+       if (core_min_uV < 0)
+               return core_min_uV;
+
+       err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+       if (err)
+               return err;
+
+       err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
+                                       PM_SUSPEND_ON);
+       if (err)
+               return err;
+
+       core_uV = regulator_get_voltage_rdev(core_rdev);
+       if (core_uV < 0)
+               return core_uV;
+
+       core_min_uV = max(cpu_min_uV + 125000, core_min_uV);
+       if (core_min_uV > core_max_uV)
+               return -EINVAL;
+
+       if (cpu_uV + 120000 > core_uV)
+               pr_err("core-cpu voltage constraint violated: %d %d\n",
+                      core_uV, cpu_uV + 120000);
+
+       rtc_uV = regulator_get_voltage_rdev(rtc_rdev);
+       if (rtc_uV < 0)
+               return rtc_uV;
+
+       if (cpu_uV + 120000 > rtc_uV)
+               pr_err("rtc-cpu voltage constraint violated: %d %d\n",
+                      rtc_uV, cpu_uV + 120000);
+
+       if (abs(core_uV - rtc_uV) > 170000)
+               pr_err("core-rtc voltage constraint violated: %d %d\n",
+                      core_uV, rtc_uV);
+
+       rtc_min_uV = max(cpu_min_uV + 125000, core_min_uV - max_spread);
+
+       err = regulator_check_voltage(rtc_rdev, &rtc_min_uV, &rtc_max_uV);
+       if (err)
+               return err;
+
+       while (core_uV != core_min_uV || rtc_uV != rtc_min_uV) {
+               if (core_uV < core_min_uV) {
+                       core_target_uV = min(core_uV + max_spread, core_min_uV);
+                       core_target_uV = min(rtc_uV + max_spread, core_target_uV);
+               } else {
+                       core_target_uV = max(core_uV - max_spread, core_min_uV);
+                       core_target_uV = max(rtc_uV - max_spread, core_target_uV);
+               }
+
+               err = regulator_set_voltage_rdev(core_rdev,
+                                                core_target_uV,
+                                                core_max_uV,
+                                                PM_SUSPEND_ON);
+               if (err)
+                       return err;
+
+               core_uV = core_target_uV;
+
+               if (rtc_uV < rtc_min_uV) {
+                       rtc_target_uV = min(rtc_uV + max_spread, rtc_min_uV);
+                       rtc_target_uV = min(core_uV + max_spread, rtc_target_uV);
+               } else {
+                       rtc_target_uV = max(rtc_uV - max_spread, rtc_min_uV);
+                       rtc_target_uV = max(core_uV - max_spread, rtc_target_uV);
+               }
+
+               err = regulator_set_voltage_rdev(rtc_rdev,
+                                                rtc_target_uV,
+                                                rtc_max_uV,
+                                                PM_SUSPEND_ON);
+               if (err)
+                       return err;
+
+               rtc_uV = rtc_target_uV;
+       }
+
+       return 0;
+}
+
+static int tegra20_core_voltage_update(struct tegra_regulator_coupler *tegra,
+                                      struct regulator_dev *cpu_rdev,
+                                      struct regulator_dev *core_rdev,
+                                      struct regulator_dev *rtc_rdev)
+{
+       int cpu_uV;
+
+       cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
+       if (cpu_uV < 0)
+               return cpu_uV;
+
+       return tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
+                                      cpu_uV, cpu_uV);
+}
+
+static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
+                                     struct regulator_dev *cpu_rdev,
+                                     struct regulator_dev *core_rdev,
+                                     struct regulator_dev *rtc_rdev)
+{
+       int cpu_min_uV_consumers = 0;
+       int cpu_max_uV = INT_MAX;
+       int cpu_min_uV = 0;
+       int cpu_uV;
+       int err;
+
+       err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
+       if (err)
+               return err;
+
+       err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
+                                       PM_SUSPEND_ON);
+       if (err)
+               return err;
+
+       err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
+                                       &cpu_max_uV, PM_SUSPEND_ON);
+       if (err)
+               return err;
+
+       cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
+       if (cpu_uV < 0)
+               return cpu_uV;
+
+       /*
+        * CPU's regulator may not have any consumers, hence the voltage
+        * must not be changed in that case because CPU simply won't
+        * survive the voltage drop if it's running on a higher frequency.
+        */
+       if (!cpu_min_uV_consumers)
+               cpu_min_uV = cpu_uV;
+
+       if (cpu_min_uV > cpu_uV) {
+               err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
+                                             cpu_uV, cpu_min_uV);
+               if (err)
+                       return err;
+
+               err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
+                                                cpu_max_uV, PM_SUSPEND_ON);
+               if (err)
+                       return err;
+       } else if (cpu_min_uV < cpu_uV)  {
+               err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
+                                                cpu_max_uV, PM_SUSPEND_ON);
+               if (err)
+                       return err;
+
+               err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
+                                             cpu_uV, cpu_min_uV);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
+                                            struct regulator_dev *rdev,
+                                            suspend_state_t state)
+{
+       struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+       struct regulator_dev *core_rdev = tegra->core_rdev;
+       struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
+       struct regulator_dev *rtc_rdev = tegra->rtc_rdev;
+
+       if ((core_rdev != rdev && cpu_rdev != rdev && rtc_rdev != rdev) ||
+           state != PM_SUSPEND_ON) {
+               pr_err("regulators are not coupled properly\n");
+               return -EINVAL;
+       }
+
+       if (rdev == cpu_rdev)
+               return tegra20_cpu_voltage_update(tegra, cpu_rdev,
+                                                 core_rdev, rtc_rdev);
+
+       if (rdev == core_rdev)
+               return tegra20_core_voltage_update(tegra, cpu_rdev,
+                                                  core_rdev, rtc_rdev);
+
+       pr_err("changing %s voltage not permitted\n", rdev_get_name(rtc_rdev));
+
+       return -EPERM;
+}
+
+static int tegra20_regulator_attach(struct regulator_coupler *coupler,
+                                   struct regulator_dev *rdev)
+{
+       struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+       struct device_node *np = rdev->dev.of_node;
+
+       if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
+           !tegra->core_rdev) {
+               tegra->core_rdev = rdev;
+               return 0;
+       }
+
+       if (of_property_read_bool(np, "nvidia,tegra-rtc-regulator") &&
+           !tegra->rtc_rdev) {
+               tegra->rtc_rdev = rdev;
+               return 0;
+       }
+
+       if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
+           !tegra->cpu_rdev) {
+               tegra->cpu_rdev = rdev;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int tegra20_regulator_detach(struct regulator_coupler *coupler,
+                                   struct regulator_dev *rdev)
+{
+       struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+
+       if (tegra->core_rdev == rdev) {
+               tegra->core_rdev = NULL;
+               return 0;
+       }
+
+       if (tegra->rtc_rdev == rdev) {
+               tegra->rtc_rdev = NULL;
+               return 0;
+       }
+
+       if (tegra->cpu_rdev == rdev) {
+               tegra->cpu_rdev = NULL;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static struct tegra_regulator_coupler tegra20_coupler = {
+       .coupler = {
+               .attach_regulator = tegra20_regulator_attach,
+               .detach_regulator = tegra20_regulator_detach,
+               .balance_voltage = tegra20_regulator_balance_voltage,
+       },
+};
+
+static int __init tegra_regulator_coupler_init(void)
+{
+       if (!of_machine_is_compatible("nvidia,tegra20"))
+               return 0;
+
+       return regulator_coupler_register(&tegra20_coupler.coupler);
+}
+arch_initcall(tegra_regulator_coupler_init);
diff --git a/drivers/soc/tegra/regulators-tegra30.c b/drivers/soc/tegra/regulators-tegra30.c
new file mode 100644 (file)
index 0000000..8e623ff
--- /dev/null
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Voltage regulators coupler for NVIDIA Tegra30
+ * Copyright (C) 2019 GRATE-DRIVER project
+ *
+ * Voltage constraints borrowed from downstream kernel sources
+ * Copyright (C) 2010-2011 NVIDIA Corporation
+ */
+
+#define pr_fmt(fmt)    "tegra voltage-coupler: " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/regulator/coupler.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include <soc/tegra/fuse.h>
+
+struct tegra_regulator_coupler {
+       struct regulator_coupler coupler;
+       struct regulator_dev *core_rdev;
+       struct regulator_dev *cpu_rdev;
+       int core_min_uV;
+};
+
+static inline struct tegra_regulator_coupler *
+to_tegra_coupler(struct regulator_coupler *coupler)
+{
+       return container_of(coupler, struct tegra_regulator_coupler, coupler);
+}
+
+static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
+                             struct regulator_dev *core_rdev)
+{
+       int core_min_uV = 0;
+       int core_max_uV;
+       int core_cur_uV;
+       int err;
+
+       if (tegra->core_min_uV > 0)
+               return tegra->core_min_uV;
+
+       core_cur_uV = regulator_get_voltage_rdev(core_rdev);
+       if (core_cur_uV < 0)
+               return core_cur_uV;
+
+       core_max_uV = max(core_cur_uV, 1200000);
+
+       err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+       if (err)
+               return err;
+
+       /*
+        * Limit minimum CORE voltage to a value left from bootloader or,
+        * if it's unreasonably low value, to the most common 1.2v or to
+        * whatever maximum value defined via board's device-tree.
+        */
+       tegra->core_min_uV = core_max_uV;
+
+       pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV);
+
+       return tegra->core_min_uV;
+}
+
+static int tegra30_core_cpu_limit(int cpu_uV)
+{
+       if (cpu_uV < 800000)
+               return 950000;
+
+       if (cpu_uV < 900000)
+               return 1000000;
+
+       if (cpu_uV < 1000000)
+               return 1100000;
+
+       if (cpu_uV < 1100000)
+               return 1200000;
+
+       if (cpu_uV < 1250000) {
+               switch (tegra_sku_info.cpu_speedo_id) {
+               case 0 ... 1:
+               case 4:
+               case 7 ... 8:
+                       return 1200000;
+
+               default:
+                       return 1300000;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
+                                 struct regulator_dev *cpu_rdev,
+                                 struct regulator_dev *core_rdev)
+{
+       int core_min_uV, core_max_uV = INT_MAX;
+       int cpu_min_uV, cpu_max_uV = INT_MAX;
+       int cpu_min_uV_consumers = 0;
+       int core_min_limited_uV;
+       int core_target_uV;
+       int cpu_target_uV;
+       int core_max_step;
+       int cpu_max_step;
+       int max_spread;
+       int core_uV;
+       int cpu_uV;
+       int err;
+
+       /*
+        * CPU voltage should not got lower than 300mV from the CORE.
+        * CPU voltage should stay below the CORE by 100mV+, depending
+        * by the CORE voltage. This applies to all Tegra30 SoC's.
+        */
+       max_spread = cpu_rdev->constraints->max_spread[0];
+       cpu_max_step = cpu_rdev->constraints->max_uV_step;
+       core_max_step = core_rdev->constraints->max_uV_step;
+
+       if (!max_spread) {
+               pr_err_once("cpu-core max-spread is undefined in device-tree\n");
+               max_spread = 300000;
+       }
+
+       if (!cpu_max_step) {
+               pr_err_once("cpu max-step is undefined in device-tree\n");
+               cpu_max_step = 150000;
+       }
+
+       if (!core_max_step) {
+               pr_err_once("core max-step is undefined in device-tree\n");
+               core_max_step = 150000;
+       }
+
+       /*
+        * The CORE voltage scaling is currently not hooked up in drivers,
+        * hence we will limit the minimum CORE voltage to a reasonable value.
+        * This should be good enough for the time being.
+        */
+       core_min_uV = tegra30_core_limit(tegra, core_rdev);
+       if (core_min_uV < 0)
+               return core_min_uV;
+
+       err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
+                                       PM_SUSPEND_ON);
+       if (err)
+               return err;
+
+       core_uV = regulator_get_voltage_rdev(core_rdev);
+       if (core_uV < 0)
+               return core_uV;
+
+       cpu_min_uV = core_min_uV - max_spread;
+
+       err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
+                                       PM_SUSPEND_ON);
+       if (err)
+               return err;
+
+       err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
+                                       &cpu_max_uV, PM_SUSPEND_ON);
+       if (err)
+               return err;
+
+       err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
+       if (err)
+               return err;
+
+       cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
+       if (cpu_uV < 0)
+               return cpu_uV;
+
+       /*
+        * CPU's regulator may not have any consumers, hence the voltage
+        * must not be changed in that case because CPU simply won't
+        * survive the voltage drop if it's running on a higher frequency.
+        */
+       if (!cpu_min_uV_consumers)
+               cpu_min_uV = cpu_uV;
+
+       /*
+        * Bootloader shall set up voltages correctly, but if it
+        * happens that there is a violation, then try to fix it
+        * at first.
+        */
+       core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
+       if (core_min_limited_uV < 0)
+               return core_min_limited_uV;
+
+       core_min_uV = max(core_min_uV, tegra30_core_cpu_limit(cpu_min_uV));
+
+       err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+       if (err)
+               return err;
+
+       if (core_min_limited_uV > core_uV) {
+               pr_err("core voltage constraint violated: %d %d %d\n",
+                      core_uV, core_min_limited_uV, cpu_uV);
+               goto update_core;
+       }
+
+       while (cpu_uV != cpu_min_uV || core_uV != core_min_uV) {
+               if (cpu_uV < cpu_min_uV) {
+                       cpu_target_uV = min(cpu_uV + cpu_max_step, cpu_min_uV);
+               } else {
+                       cpu_target_uV = max(cpu_uV - cpu_max_step, cpu_min_uV);
+                       cpu_target_uV = max(core_uV - max_spread, cpu_target_uV);
+               }
+
+               err = regulator_set_voltage_rdev(cpu_rdev,
+                                                cpu_target_uV,
+                                                cpu_max_uV,
+                                                PM_SUSPEND_ON);
+               if (err)
+                       return err;
+
+               cpu_uV = cpu_target_uV;
+update_core:
+               core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
+               if (core_min_limited_uV < 0)
+                       return core_min_limited_uV;
+
+               core_target_uV = max(core_min_limited_uV, core_min_uV);
+
+               if (core_uV < core_target_uV) {
+                       core_target_uV = min(core_target_uV, core_uV + core_max_step);
+                       core_target_uV = min(core_target_uV, cpu_uV + max_spread);
+               } else {
+                       core_target_uV = max(core_target_uV, core_uV - core_max_step);
+               }
+
+               err = regulator_set_voltage_rdev(core_rdev,
+                                                core_target_uV,
+                                                core_max_uV,
+                                                PM_SUSPEND_ON);
+               if (err)
+                       return err;
+
+               core_uV = core_target_uV;
+       }
+
+       return 0;
+}
+
+static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler,
+                                            struct regulator_dev *rdev,
+                                            suspend_state_t state)
+{
+       struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+       struct regulator_dev *core_rdev = tegra->core_rdev;
+       struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
+
+       if ((core_rdev != rdev && cpu_rdev != rdev) || state != PM_SUSPEND_ON) {
+               pr_err("regulators are not coupled properly\n");
+               return -EINVAL;
+       }
+
+       return tegra30_voltage_update(tegra, cpu_rdev, core_rdev);
+}
+
+static int tegra30_regulator_attach(struct regulator_coupler *coupler,
+                                   struct regulator_dev *rdev)
+{
+       struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+       struct device_node *np = rdev->dev.of_node;
+
+       if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
+           !tegra->core_rdev) {
+               tegra->core_rdev = rdev;
+               return 0;
+       }
+
+       if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
+           !tegra->cpu_rdev) {
+               tegra->cpu_rdev = rdev;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int tegra30_regulator_detach(struct regulator_coupler *coupler,
+                                   struct regulator_dev *rdev)
+{
+       struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+
+       if (tegra->core_rdev == rdev) {
+               tegra->core_rdev = NULL;
+               return 0;
+       }
+
+       if (tegra->cpu_rdev == rdev) {
+               tegra->cpu_rdev = NULL;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static struct tegra_regulator_coupler tegra30_coupler = {
+       .coupler = {
+               .attach_regulator = tegra30_regulator_attach,
+               .detach_regulator = tegra30_regulator_detach,
+               .balance_voltage = tegra30_regulator_balance_voltage,
+       },
+};
+
+static int __init tegra_regulator_coupler_init(void)
+{
+       if (!of_machine_is_compatible("nvidia,tegra30"))
+               return 0;
+
+       return regulator_coupler_register(&tegra30_coupler.coupler);
+}
+arch_initcall(tegra_regulator_coupler_init);
index b3868d3..788b5cd 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS)   += knav_qmss.o
 knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o
 obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA)   += knav_dma.o
 obj-$(CONFIG_AMX3_PM)                  += pm33xx.o
+obj-$(CONFIG_ARCH_OMAP2PLUS)           += omap_prm.o
 obj-$(CONFIG_WKUP_M3_IPC)              += wkup_m3_ipc.o
 obj-$(CONFIG_TI_SCI_PM_DOMAINS)                += ti_sci_pm_domains.o
 obj-$(CONFIG_TI_SCI_INTA_MSI_DOMAIN)   += ti_sci_inta_msi.o
diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
new file mode 100644 (file)
index 0000000..96c6f77
--- /dev/null
@@ -0,0 +1,391 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OMAP2+ PRM driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *     Tero Kristo <t-kristo@ti.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/delay.h>
+
+#include <linux/platform_data/ti-prm.h>
+
+struct omap_rst_map {
+       s8 rst;
+       s8 st;
+};
+
+struct omap_prm_data {
+       u32 base;
+       const char *name;
+       const char *clkdm_name;
+       u16 rstctrl;
+       u16 rstst;
+       const struct omap_rst_map *rstmap;
+       u8 flags;
+};
+
+struct omap_prm {
+       const struct omap_prm_data *data;
+       void __iomem *base;
+};
+
+struct omap_reset_data {
+       struct reset_controller_dev rcdev;
+       struct omap_prm *prm;
+       u32 mask;
+       spinlock_t lock;
+       struct clockdomain *clkdm;
+       struct device *dev;
+};
+
+#define to_omap_reset_data(p) container_of((p), struct omap_reset_data, rcdev)
+
+#define OMAP_MAX_RESETS                8
+#define OMAP_RESET_MAX_WAIT    10000
+
+#define OMAP_PRM_HAS_RSTCTRL   BIT(0)
+#define OMAP_PRM_HAS_RSTST     BIT(1)
+#define OMAP_PRM_HAS_NO_CLKDM  BIT(2)
+
+#define OMAP_PRM_HAS_RESETS    (OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_RSTST)
+
+static const struct omap_rst_map rst_map_0[] = {
+       { .rst = 0, .st = 0 },
+       { .rst = -1 },
+};
+
+static const struct omap_rst_map rst_map_01[] = {
+       { .rst = 0, .st = 0 },
+       { .rst = 1, .st = 1 },
+       { .rst = -1 },
+};
+
+static const struct omap_rst_map rst_map_012[] = {
+       { .rst = 0, .st = 0 },
+       { .rst = 1, .st = 1 },
+       { .rst = 2, .st = 2 },
+       { .rst = -1 },
+};
+
+static const struct omap_prm_data omap4_prm_data[] = {
+       { .name = "tesla", .base = 0x4a306400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { .name = "core", .base = 0x4a306700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ducati", .rstmap = rst_map_012 },
+       { .name = "ivahd", .base = 0x4a306f00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 },
+       { .name = "device", .base = 0x4a307b00, .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
+       { },
+};
+
+static const struct omap_prm_data omap5_prm_data[] = {
+       { .name = "dsp", .base = 0x4ae06400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { .name = "core", .base = 0x4ae06700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu", .rstmap = rst_map_012 },
+       { .name = "iva", .base = 0x4ae07200, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 },
+       { .name = "device", .base = 0x4ae07c00, .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
+       { },
+};
+
+static const struct omap_prm_data dra7_prm_data[] = {
+       { .name = "dsp1", .base = 0x4ae06400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { .name = "ipu", .base = 0x4ae06500, .rstctrl = 0x10, .rstst = 0x14, .clkdm_name = "ipu1", .rstmap = rst_map_012 },
+       { .name = "core", .base = 0x4ae06700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu2", .rstmap = rst_map_012 },
+       { .name = "iva", .base = 0x4ae06f00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 },
+       { .name = "dsp2", .base = 0x4ae07b00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { .name = "eve1", .base = 0x4ae07b40, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { .name = "eve2", .base = 0x4ae07b80, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { .name = "eve3", .base = 0x4ae07bc0, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { .name = "eve4", .base = 0x4ae07c00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 },
+       { },
+};
+
+static const struct omap_rst_map am3_per_rst_map[] = {
+       { .rst = 1 },
+       { .rst = -1 },
+};
+
+static const struct omap_rst_map am3_wkup_rst_map[] = {
+       { .rst = 3, .st = 5 },
+       { .rst = -1 },
+};
+
+static const struct omap_prm_data am3_prm_data[] = {
+       { .name = "per", .base = 0x44e00c00, .rstctrl = 0x0, .rstmap = am3_per_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL, .clkdm_name = "pruss_ocp" },
+       { .name = "wkup", .base = 0x44e00d00, .rstctrl = 0x0, .rstst = 0xc, .rstmap = am3_wkup_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
+       { .name = "device", .base = 0x44e00f00, .rstctrl = 0x0, .rstst = 0x8, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
+       { .name = "gfx", .base = 0x44e01100, .rstctrl = 0x4, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3" },
+       { },
+};
+
+static const struct omap_rst_map am4_per_rst_map[] = {
+       { .rst = 1, .st = 0 },
+       { .rst = -1 },
+};
+
+static const struct omap_rst_map am4_device_rst_map[] = {
+       { .rst = 0, .st = 1 },
+       { .rst = 1, .st = 0 },
+       { .rst = -1 },
+};
+
+static const struct omap_prm_data am4_prm_data[] = {
+       { .name = "gfx", .base = 0x44df0400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3" },
+       { .name = "per", .base = 0x44df0800, .rstctrl = 0x10, .rstst = 0x14, .rstmap = am4_per_rst_map, .clkdm_name = "pruss_ocp" },
+       { .name = "wkup", .base = 0x44df2000, .rstctrl = 0x10, .rstst = 0x14, .rstmap = am3_wkup_rst_map, .flags = OMAP_PRM_HAS_NO_CLKDM },
+       { .name = "device", .base = 0x44df4000, .rstctrl = 0x0, .rstst = 0x4, .rstmap = am4_device_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
+       { },
+};
+
+static const struct of_device_id omap_prm_id_table[] = {
+       { .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data },
+       { .compatible = "ti,omap5-prm-inst", .data = omap5_prm_data },
+       { .compatible = "ti,dra7-prm-inst", .data = dra7_prm_data },
+       { .compatible = "ti,am3-prm-inst", .data = am3_prm_data },
+       { .compatible = "ti,am4-prm-inst", .data = am4_prm_data },
+       { },
+};
+
+static bool _is_valid_reset(struct omap_reset_data *reset, unsigned long id)
+{
+       if (reset->mask & BIT(id))
+               return true;
+
+       return false;
+}
+
+static int omap_reset_get_st_bit(struct omap_reset_data *reset,
+                                unsigned long id)
+{
+       const struct omap_rst_map *map = reset->prm->data->rstmap;
+
+       while (map->rst >= 0) {
+               if (map->rst == id)
+                       return map->st;
+
+               map++;
+       }
+
+       return id;
+}
+
+static int omap_reset_status(struct reset_controller_dev *rcdev,
+                            unsigned long id)
+{
+       struct omap_reset_data *reset = to_omap_reset_data(rcdev);
+       u32 v;
+       int st_bit = omap_reset_get_st_bit(reset, id);
+       bool has_rstst = reset->prm->data->rstst ||
+               (reset->prm->data->flags & OMAP_PRM_HAS_RSTST);
+
+       /* Check if we have rstst */
+       if (!has_rstst)
+               return -ENOTSUPP;
+
+       /* Check if hw reset line is asserted */
+       v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
+       if (v & BIT(id))
+               return 1;
+
+       /*
+        * Check reset status, high value means reset sequence has been
+        * completed successfully so we can return 0 here (reset deasserted)
+        */
+       v = readl_relaxed(reset->prm->base + reset->prm->data->rstst);
+       v >>= st_bit;
+       v &= 1;
+
+       return !v;
+}
+
+static int omap_reset_assert(struct reset_controller_dev *rcdev,
+                            unsigned long id)
+{
+       struct omap_reset_data *reset = to_omap_reset_data(rcdev);
+       u32 v;
+       unsigned long flags;
+
+       /* assert the reset control line */
+       spin_lock_irqsave(&reset->lock, flags);
+       v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
+       v |= 1 << id;
+       writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
+       spin_unlock_irqrestore(&reset->lock, flags);
+
+       return 0;
+}
+
+static int omap_reset_deassert(struct reset_controller_dev *rcdev,
+                              unsigned long id)
+{
+       struct omap_reset_data *reset = to_omap_reset_data(rcdev);
+       u32 v;
+       int st_bit;
+       bool has_rstst;
+       unsigned long flags;
+       struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev);
+       int ret = 0;
+
+       has_rstst = reset->prm->data->rstst ||
+               (reset->prm->data->flags & OMAP_PRM_HAS_RSTST);
+
+       if (has_rstst) {
+               st_bit = omap_reset_get_st_bit(reset, id);
+
+               /* Clear the reset status by writing 1 to the status bit */
+               v = 1 << st_bit;
+               writel_relaxed(v, reset->prm->base + reset->prm->data->rstst);
+       }
+
+       if (reset->clkdm)
+               pdata->clkdm_deny_idle(reset->clkdm);
+
+       /* de-assert the reset control line */
+       spin_lock_irqsave(&reset->lock, flags);
+       v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
+       v &= ~(1 << id);
+       writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
+       spin_unlock_irqrestore(&reset->lock, flags);
+
+       if (!has_rstst)
+               goto exit;
+
+       /* wait for the status to be set */
+       ret = readl_relaxed_poll_timeout(reset->prm->base +
+                                        reset->prm->data->rstst,
+                                        v, v & BIT(st_bit), 1,
+                                        OMAP_RESET_MAX_WAIT);
+       if (ret)
+               pr_err("%s: timedout waiting for %s:%lu\n", __func__,
+                      reset->prm->data->name, id);
+
+exit:
+       if (reset->clkdm)
+               pdata->clkdm_allow_idle(reset->clkdm);
+
+       return ret;
+}
+
+static const struct reset_control_ops omap_reset_ops = {
+       .assert         = omap_reset_assert,
+       .deassert       = omap_reset_deassert,
+       .status         = omap_reset_status,
+};
+
+static int omap_prm_reset_xlate(struct reset_controller_dev *rcdev,
+                               const struct of_phandle_args *reset_spec)
+{
+       struct omap_reset_data *reset = to_omap_reset_data(rcdev);
+
+       if (!_is_valid_reset(reset, reset_spec->args[0]))
+               return -EINVAL;
+
+       return reset_spec->args[0];
+}
+
+static int omap_prm_reset_init(struct platform_device *pdev,
+                              struct omap_prm *prm)
+{
+       struct omap_reset_data *reset;
+       const struct omap_rst_map *map;
+       struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev);
+       char buf[32];
+
+       /*
+        * Check if we have controllable resets. If either rstctrl is non-zero
+        * or OMAP_PRM_HAS_RSTCTRL flag is set, we have reset control register
+        * for the domain.
+        */
+       if (!prm->data->rstctrl && !(prm->data->flags & OMAP_PRM_HAS_RSTCTRL))
+               return 0;
+
+       /* Check if we have the pdata callbacks in place */
+       if (!pdata || !pdata->clkdm_lookup || !pdata->clkdm_deny_idle ||
+           !pdata->clkdm_allow_idle)
+               return -EINVAL;
+
+       map = prm->data->rstmap;
+       if (!map)
+               return -EINVAL;
+
+       reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
+       if (!reset)
+               return -ENOMEM;
+
+       reset->rcdev.owner = THIS_MODULE;
+       reset->rcdev.ops = &omap_reset_ops;
+       reset->rcdev.of_node = pdev->dev.of_node;
+       reset->rcdev.nr_resets = OMAP_MAX_RESETS;
+       reset->rcdev.of_xlate = omap_prm_reset_xlate;
+       reset->rcdev.of_reset_n_cells = 1;
+       reset->dev = &pdev->dev;
+       spin_lock_init(&reset->lock);
+
+       reset->prm = prm;
+
+       sprintf(buf, "%s_clkdm", prm->data->clkdm_name ? prm->data->clkdm_name :
+               prm->data->name);
+
+       if (!(prm->data->flags & OMAP_PRM_HAS_NO_CLKDM)) {
+               reset->clkdm = pdata->clkdm_lookup(buf);
+               if (!reset->clkdm)
+                       return -EINVAL;
+       }
+
+       while (map->rst >= 0) {
+               reset->mask |= BIT(map->rst);
+               map++;
+       }
+
+       return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
+}
+
+static int omap_prm_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       const struct omap_prm_data *data;
+       struct omap_prm *prm;
+       const struct of_device_id *match;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+
+       match = of_match_device(omap_prm_id_table, &pdev->dev);
+       if (!match)
+               return -ENOTSUPP;
+
+       prm = devm_kzalloc(&pdev->dev, sizeof(*prm), GFP_KERNEL);
+       if (!prm)
+               return -ENOMEM;
+
+       data = match->data;
+
+       while (data->base != res->start) {
+               if (!data->base)
+                       return -EINVAL;
+               data++;
+       }
+
+       prm->data = data;
+
+       prm->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(prm->base))
+               return PTR_ERR(prm->base);
+
+       return omap_prm_reset_init(pdev, prm);
+}
+
+static struct platform_driver omap_prm_driver = {
+       .probe = omap_prm_probe,
+       .driver = {
+               .name           = KBUILD_MODNAME,
+               .of_match_table = omap_prm_id_table,
+       },
+};
+builtin_platform_driver(omap_prm_driver);
index 600f57c..23d90cb 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * ZynqMP Generic PM domain support
  *
- *  Copyright (C) 2015-2018 Xilinx, Inc.
+ *  Copyright (C) 2015-2019 Xilinx, Inc.
  *
  *  Davorin Mista <davorin.mista@aggios.com>
  *  Jolly Shah <jollys@xilinx.com>
@@ -25,6 +25,8 @@
 
 static const struct zynqmp_eemi_ops *eemi_ops;
 
+static int min_capability;
+
 /**
  * struct zynqmp_pm_domain - Wrapper around struct generic_pm_domain
  * @gpd:               Generic power domain
@@ -106,7 +108,7 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
        int ret;
        struct pm_domain_data *pdd, *tmp;
        struct zynqmp_pm_domain *pd;
-       u32 capabilities = 0;
+       u32 capabilities = min_capability;
        bool may_wakeup;
 
        if (!eemi_ops->set_requirement)
@@ -283,6 +285,10 @@ static int zynqmp_gpd_probe(struct platform_device *pdev)
        if (!domains)
                return -ENOMEM;
 
+       if (!of_device_is_compatible(dev->parent->of_node,
+                                    "xlnx,zynqmp-firmware"))
+               min_capability = ZYNQMP_PM_CAPABILITY_UNUSABLE;
+
        for (i = 0; i < ZYNQMP_NUM_DOMAINS; i++, pd++) {
                pd->node_id = 0;
                pd->gpd.name = kasprintf(GFP_KERNEL, "domain%d", i);
index 2aac1e0..51c665a 100644 (file)
@@ -805,8 +805,8 @@ s32 create_dir(struct inode *inode, struct chain_t *p_dir,
 s32 create_file(struct inode *inode, struct chain_t *p_dir,
                struct uni_name_t *p_uniname, u8 mode, struct file_id_t *fid);
 void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry);
-s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry,
-               struct uni_name_t *p_uniname, struct file_id_t *fid);
+s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry,
+                     struct uni_name_t *p_uniname, struct file_id_t *fid);
 s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry,
              struct chain_t *p_newdir, struct uni_name_t *p_uniname,
              struct file_id_t *fid);
index d2d3447..794000e 100644 (file)
@@ -192,8 +192,6 @@ static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
 
        exfat_bitmap_clear((u8 *)p_fs->vol_amap[i]->b_data, b);
 
-       return sector_write(sb, sector, p_fs->vol_amap[i], 0);
-
 #ifdef CONFIG_EXFAT_DISCARD
        if (opts->discard) {
                ret = sb_issue_discard(sb, START_SECTOR(clu),
@@ -202,9 +200,13 @@ static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
                if (ret == -EOPNOTSUPP) {
                        pr_warn("discard not supported by device, disabling");
                        opts->discard = 0;
+               } else {
+                       return ret;
                }
        }
 #endif /* CONFIG_EXFAT_DISCARD */
+
+       return sector_write(sb, sector, p_fs->vol_amap[i], 0);
 }
 
 static u32 test_alloc_bitmap(struct super_block *sb, u32 clu)
@@ -2322,8 +2324,8 @@ void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry)
        fs_func->delete_dir_entry(sb, p_dir, entry, 0, num_entries);
 }
 
-s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
-               struct uni_name_t *p_uniname, struct file_id_t *fid)
+s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
+                     struct uni_name_t *p_uniname, struct file_id_t *fid)
 {
        s32 ret, newentry = -1, num_old_entries, num_new_entries;
        sector_t sector_old, sector_new;
index 6e48190..9f91853 100644 (file)
@@ -1262,8 +1262,8 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
        fs_set_vol_flags(sb, VOL_DIRTY);
 
        if (olddir.dir == newdir.dir)
-               ret = rename_file(new_parent_inode, &olddir, dentry, &uni_name,
-                                 fid);
+               ret = exfat_rename_file(new_parent_inode, &olddir, dentry,
+                                       &uni_name, fid);
        else
                ret = move_file(new_parent_inode, &olddir, dentry, &newdir,
                                &uni_name, fid);
index e763205..f61e373 100644 (file)
@@ -63,11 +63,17 @@ static int init_display(struct fbtft_par *par)
 {
        int ret;
 
-       /* Set CS active high */
-       par->spi->mode |= SPI_CS_HIGH;
+       /*
+        * Set CS active inverse polarity: just setting SPI_CS_HIGH does not
+        * work with GPIO based chip selects that are logically active high
+        * but inverted inside the GPIO library, so enforce inverted
+        * semantics.
+        */
+       par->spi->mode ^= SPI_CS_HIGH;
        ret = spi_setup(par->spi);
        if (ret) {
-               dev_err(par->info->device, "Could not set SPI_CS_HIGH\n");
+               dev_err(par->info->device,
+                       "Could not set inverse CS polarity\n");
                return ret;
        }
 
index 27cc8ea..76b25df 100644 (file)
@@ -150,10 +150,17 @@ static int init_display(struct fbtft_par *par)
 
        /* enable SPI interface by having CS and MOSI low during reset */
        save_mode = par->spi->mode;
-       par->spi->mode |= SPI_CS_HIGH;
-       ret = spi_setup(par->spi); /* set CS inactive low */
+       /*
+        * Set CS active inverse polarity: just setting SPI_CS_HIGH does not
+        * work with GPIO based chip selects that are logically active high
+        * but inverted inside the GPIO library, so enforce inverted
+        * semantics.
+        */
+       par->spi->mode ^= SPI_CS_HIGH;
+       ret = spi_setup(par->spi);
        if (ret) {
-               dev_err(par->info->device, "Could not set SPI_CS_HIGH\n");
+               dev_err(par->info->device,
+                       "Could not set inverse CS polarity\n");
                return ret;
        }
        write_reg(par, 0x00); /* make sure mode is set */
index ffb8498..d3e098b 100644 (file)
@@ -913,7 +913,7 @@ static int fbtft_init_display_from_property(struct fbtft_par *par)
        if (count == 0)
                return -EINVAL;
 
-       values = kmalloc_array(count, sizeof(*values), GFP_KERNEL);
+       values = kmalloc_array(count + 1, sizeof(*values), GFP_KERNEL);
        if (!values)
                return -ENOMEM;
 
@@ -926,9 +926,9 @@ static int fbtft_init_display_from_property(struct fbtft_par *par)
                gpiod_set_value(par->gpio.cs, 0);  /* Activate chip */
 
        index = -1;
-       while (index < count) {
-               val = values[++index];
+       val = values[++index];
 
+       while (index < count) {
                if (val & FBTFT_OF_INIT_CMD) {
                        val &= 0xFFFF;
                        i = 0;
index fb395cf..f20ab21 100644 (file)
@@ -6,6 +6,7 @@
 config NET_VENDOR_HP
        bool "HP devices"
        default y
+       depends on ETHERNET
        depends on ISA || EISA || PCI
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y.
index 1b9b436..a20c0bf 100644 (file)
@@ -571,8 +571,7 @@ static int gigaset_initcshw(struct cardstate *cs)
 {
        struct usb_cardstate *ucs;
 
-       cs->hw.usb = ucs =
-               kmalloc(sizeof(struct usb_cardstate), GFP_KERNEL);
+       cs->hw.usb = ucs = kzalloc(sizeof(struct usb_cardstate), GFP_KERNEL);
        if (!ucs) {
                pr_err("out of memory\n");
                return -ENOMEM;
@@ -584,9 +583,6 @@ static int gigaset_initcshw(struct cardstate *cs)
        ucs->bchars[3] = 0;
        ucs->bchars[4] = 0x11;
        ucs->bchars[5] = 0x13;
-       ucs->bulk_out_buffer = NULL;
-       ucs->bulk_out_urb = NULL;
-       ucs->read_urb = NULL;
        tasklet_init(&cs->write_tasklet,
                     gigaset_modem_fill, (unsigned long) cs);
 
@@ -685,6 +681,11 @@ static int gigaset_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
+       if (hostif->desc.bNumEndpoints < 2) {
+               dev_err(&interface->dev, "missing endpoints\n");
+               return -ENODEV;
+       }
+
        dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
 
        /* allocate memory for our device state and initialize it */
@@ -704,6 +705,12 @@ static int gigaset_probe(struct usb_interface *interface,
 
        endpoint = &hostif->endpoint[0].desc;
 
+       if (!usb_endpoint_is_bulk_out(endpoint)) {
+               dev_err(&interface->dev, "missing bulk-out endpoint\n");
+               retval = -ENODEV;
+               goto error;
+       }
+
        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
        ucs->bulk_out_size = buffer_size;
        ucs->bulk_out_epnum = usb_endpoint_num(endpoint);
@@ -723,6 +730,12 @@ static int gigaset_probe(struct usb_interface *interface,
 
        endpoint = &hostif->endpoint[1].desc;
 
+       if (!usb_endpoint_is_int_in(endpoint)) {
+               dev_err(&interface->dev, "missing int-in endpoint\n");
+               retval = -ENODEV;
+               goto error;
+       }
+
        ucs->busy = 0;
 
        ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
index 5319909..e7f4ddc 100644 (file)
@@ -3,6 +3,7 @@ config OCTEON_ETHERNET
        tristate "Cavium Networks Octeon Ethernet support"
        depends on CAVIUM_OCTEON_SOC || COMPILE_TEST
        depends on NETDEVICES
+       depends on BROKEN
        select PHYLIB
        select MDIO_OCTEON
        help
index a6886cc..56d116d 100644 (file)
@@ -41,7 +41,7 @@ struct ql_stats {
        int stat_offset;
 };
 
-#define QL_SIZEOF(m) FIELD_SIZEOF(struct ql_adapter, m)
+#define QL_SIZEOF(m) sizeof_field(struct ql_adapter, m)
 #define QL_OFF(m) offsetof(struct ql_adapter, m)
 
 static const struct ql_stats ql_gstrings_stats[] = {
index 4fac9dc..a7cac07 100644 (file)
@@ -70,7 +70,7 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
        phost_conf = pusbd->actconfig;
        pconf_desc = &phost_conf->desc;
 
-       phost_iface = &usb_intf->altsetting[0];
+       phost_iface = usb_intf->cur_altsetting;
        piface_desc = &phost_iface->desc;
 
        pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
index ba12882..a87562f 100644 (file)
@@ -247,7 +247,7 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter)
 
        pdvobjpriv->padapter = padapter;
        padapter->eeprom_address_size = 6;
-       phost_iface = &pintf->altsetting[0];
+       phost_iface = pintf->cur_altsetting;
        piface_desc = &phost_iface->desc;
        pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
        if (pusbd->speed == USB_SPEED_HIGH) {
index 02148a2..4458c1e 100644 (file)
@@ -3309,7 +3309,7 @@ static int __init vchiq_driver_init(void)
        return 0;
 
 region_unregister:
-       platform_driver_unregister(&vchiq_driver);
+       unregister_chrdev_region(vchiq_devid, 1);
 
 class_destroy:
        class_destroy(vchiq_class);
index b722e97..df2640a 100644 (file)
@@ -679,7 +679,7 @@ void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
        struct ieee80211_sta *sta = control ? control->sta : NULL;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       size_t driver_data_room = FIELD_SIZEOF(struct ieee80211_tx_info,
+       size_t driver_data_room = sizeof_field(struct ieee80211_tx_info,
                                               rate_driver_data);
 
        compiletime_assert(sizeof(struct wfx_tx_priv) <= driver_data_room,
index ac13666..082c16a 100644 (file)
@@ -4,6 +4,7 @@ config PRISM2_USB
        depends on WLAN && USB && CFG80211
        select WIRELESS_EXT
        select WEXT_PRIV
+       select CRC32
        help
          This is the wlan-ng prism 2.5/3 USB driver for a wide range of
          old USB wireless devices.
index e877b91..30ea37e 100644 (file)
@@ -708,7 +708,7 @@ static int __init cxgbit_init(void)
        pr_info("%s dcb enabled.\n", DRV_NAME);
        register_dcbevent_notifier(&cxgbit_dcbevent_nb);
 #endif
-       BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, cb) <
+       BUILD_BUG_ON(sizeof_field(struct sk_buff, cb) <
                     sizeof(union cxgbit_skb_cb));
        return 0;
 }
index 13b0269..cf2367b 100644 (file)
@@ -554,6 +554,13 @@ static int check_mem_type(unsigned long start, size_t num_pages)
        struct mm_struct *mm = current->mm;
        int rc;
 
+       /*
+        * Allow kernel address to register with OP-TEE as kernel
+        * pages are configured as normal memory only.
+        */
+       if (virt_addr_valid(start))
+               return 0;
+
        down_read(&mm->mmap_sem);
        rc = __check_mem_type(find_vma(mm, start),
                              start + num_pages * PAGE_SIZE);
index 1854a3d..b830e0a 100644 (file)
@@ -643,11 +643,6 @@ static struct optee *optee_probe(struct device_node *np)
        if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
                pr_info("dynamic shared memory is enabled\n");
 
-       rc = optee_enumerate_devices();
-       if (rc)
-               goto err;
-
-       pr_info("initialized driver\n");
        return optee;
 err:
        if (optee) {
@@ -702,9 +697,10 @@ static struct optee *optee_svc;
 
 static int __init optee_driver_init(void)
 {
-       struct device_node *fw_np;
-       struct device_node *np;
-       struct optee *optee;
+       struct device_node *fw_np = NULL;
+       struct device_node *np = NULL;
+       struct optee *optee = NULL;
+       int rc = 0;
 
        /* Node is supposed to be below /firmware */
        fw_np = of_find_node_by_name(NULL, "firmware");
@@ -723,6 +719,14 @@ static int __init optee_driver_init(void)
        if (IS_ERR(optee))
                return PTR_ERR(optee);
 
+       rc = optee_enumerate_devices();
+       if (rc) {
+               optee_remove(optee);
+               return rc;
+       }
+
+       pr_info("initialized driver\n");
+
        optee_svc = optee;
 
        return 0;
index de1d9b8..0332a53 100644 (file)
@@ -17,6 +17,7 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
 {
        unsigned int order = get_order(size);
        struct page *page;
+       int rc = 0;
 
        page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
        if (!page)
@@ -26,12 +27,21 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
        shm->paddr = page_to_phys(page);
        shm->size = PAGE_SIZE << order;
 
-       return 0;
+       if (shm->flags & TEE_SHM_DMA_BUF) {
+               shm->flags |= TEE_SHM_REGISTER;
+               rc = optee_shm_register(shm->ctx, shm, &page, 1 << order,
+                                       (unsigned long)shm->kaddr);
+       }
+
+       return rc;
 }
 
 static void pool_op_free(struct tee_shm_pool_mgr *poolm,
                         struct tee_shm *shm)
 {
+       if (shm->flags & TEE_SHM_DMA_BUF)
+               optee_shm_unregister(shm->ctx, shm);
+
        free_pages((unsigned long)shm->kaddr, get_order(shm->size));
        shm->kaddr = NULL;
 }
index 001a21a..79b2786 100644 (file)
@@ -108,7 +108,7 @@ config THERMAL_DEFAULT_GOV_USER_SPACE
 
 config THERMAL_DEFAULT_GOV_POWER_ALLOCATOR
        bool "power_allocator"
-       select THERMAL_GOV_POWER_ALLOCATOR
+       depends on THERMAL_GOV_POWER_ALLOCATOR
        help
          Select this if you want to control temperature based on
          system and device power allocation. This governor can only
@@ -144,6 +144,7 @@ config THERMAL_GOV_USER_SPACE
 
 config THERMAL_GOV_POWER_ALLOCATOR
        bool "Power allocator thermal governor"
+       depends on ENERGY_MODEL
        help
          Enable this to manage platform thermals by dynamically
          allocating and limiting power to devices.
@@ -348,6 +349,17 @@ config MTK_THERMAL
          Enable this option if you want to have support for thermal management
          controller present in Mediatek SoCs
 
+config AMLOGIC_THERMAL
+       tristate "Amlogic Thermal Support"
+       default ARCH_MESON
+       depends on OF && ARCH_MESON
+       help
+         If you say yes here you get support for Amlogic Thermal
+         for G12 SoC Family.
+
+         This driver can also be built as a module. If so, the module will
+         be called amlogic_thermal.
+
 menu "Intel thermal drivers"
 depends on X86 || X86_INTEL_QUARK || COMPILE_TEST
 source "drivers/thermal/intel/Kconfig"
index 74a37c7..baeb70b 100644 (file)
@@ -54,3 +54,4 @@ obj-$(CONFIG_MTK_THERMAL)     += mtk_thermal.o
 obj-$(CONFIG_GENERIC_ADC_THERMAL)      += thermal-generic-adc.o
 obj-$(CONFIG_ZX2967_THERMAL)   += zx2967_thermal.o
 obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
+obj-$(CONFIG_AMLOGIC_THERMAL)     += amlogic_thermal.o
diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c
new file mode 100644 (file)
index 0000000..8a9e9bc
--- /dev/null
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Amlogic Thermal Sensor Driver
+ *
+ * Copyright (C) 2017 Huan Biao <huan.biao@amlogic.com>
+ * Copyright (C) 2019 Guillaume La Roque <glaroque@baylibre.com>
+ *
+ * Register value to celsius temperature formulas:
+ *     Read_Val            m * U
+ * U = ---------, Uptat = ---------
+ *     2^16              1 + n * U
+ *
+ * Temperature = A * ( Uptat + u_efuse / 2^16 )- B
+ *
+ *  A B m n : calibration parameters
+ *  u_efuse : fused calibration value, it's a signed 16 bits value
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/thermal.h>
+
+#include "thermal_core.h"
+
+#define TSENSOR_CFG_REG1                       0x4
+       #define TSENSOR_CFG_REG1_RSET_VBG       BIT(12)
+       #define TSENSOR_CFG_REG1_RSET_ADC       BIT(11)
+       #define TSENSOR_CFG_REG1_VCM_EN         BIT(10)
+       #define TSENSOR_CFG_REG1_VBG_EN         BIT(9)
+       #define TSENSOR_CFG_REG1_OUT_CTL        BIT(6)
+       #define TSENSOR_CFG_REG1_FILTER_EN      BIT(5)
+       #define TSENSOR_CFG_REG1_DEM_EN         BIT(3)
+       #define TSENSOR_CFG_REG1_CH_SEL         GENMASK(1, 0)
+       #define TSENSOR_CFG_REG1_ENABLE         \
+               (TSENSOR_CFG_REG1_FILTER_EN |   \
+                TSENSOR_CFG_REG1_VCM_EN |      \
+                TSENSOR_CFG_REG1_VBG_EN |      \
+                TSENSOR_CFG_REG1_DEM_EN |      \
+                TSENSOR_CFG_REG1_CH_SEL)
+
+#define TSENSOR_STAT0                  0x40
+
+#define TSENSOR_STAT9                  0x64
+
+#define TSENSOR_READ_TEMP_MASK         GENMASK(15, 0)
+#define TSENSOR_TEMP_MASK              GENMASK(11, 0)
+
+#define TSENSOR_TRIM_SIGN_MASK         BIT(15)
+#define TSENSOR_TRIM_TEMP_MASK         GENMASK(14, 0)
+#define TSENSOR_TRIM_VERSION_MASK      GENMASK(31, 24)
+
+#define TSENSOR_TRIM_VERSION(_version) \
+       FIELD_GET(TSENSOR_TRIM_VERSION_MASK, _version)
+
+#define TSENSOR_TRIM_CALIB_VALID_MASK  (GENMASK(3, 2) | BIT(7))
+
+#define TSENSOR_CALIB_OFFSET   1
+#define TSENSOR_CALIB_SHIFT    4
+
+/**
+ * struct amlogic_thermal_soc_calib_data
+ * @A, B, m, n: calibration parameters
+ * This structure is required for configuration of amlogic thermal driver.
+ */
+struct amlogic_thermal_soc_calib_data {
+       int A;
+       int B;
+       int m;
+       int n;
+};
+
+/**
+ * struct amlogic_thermal_data
+ * @u_efuse_off: register offset to read fused calibration value
+ * @calibration_parameters: calibration parameters structure pointer
+ * @regmap_config: regmap config for the device
+ * This structure is required for configuration of amlogic thermal driver.
+ */
+struct amlogic_thermal_data {
+       int u_efuse_off;
+       const struct amlogic_thermal_soc_calib_data *calibration_parameters;
+       const struct regmap_config *regmap_config;
+};
+
+struct amlogic_thermal {
+       struct platform_device *pdev;
+       const struct amlogic_thermal_data *data;
+       struct regmap *regmap;
+       struct regmap *sec_ao_map;
+       struct clk *clk;
+       struct thermal_zone_device *tzd;
+       u32 trim_info;
+};
+
+/*
+ * Calculate a temperature value from a temperature code.
+ * The unit of the temperature is degree milliCelsius.
+ */
+static int amlogic_thermal_code_to_millicelsius(struct amlogic_thermal *pdata,
+                                               int temp_code)
+{
+       const struct amlogic_thermal_soc_calib_data *param =
+                                       pdata->data->calibration_parameters;
+       int temp;
+       s64 factor, Uptat, uefuse;
+
+       uefuse = pdata->trim_info & TSENSOR_TRIM_SIGN_MASK ?
+                            ~(pdata->trim_info & TSENSOR_TRIM_TEMP_MASK) + 1 :
+                            (pdata->trim_info & TSENSOR_TRIM_TEMP_MASK);
+
+       factor = param->n * temp_code;
+       factor = div_s64(factor, 100);
+
+       Uptat = temp_code * param->m;
+       Uptat = div_s64(Uptat, 100);
+       Uptat = Uptat * BIT(16);
+       Uptat = div_s64(Uptat, BIT(16) + factor);
+
+       temp = (Uptat + uefuse) * param->A;
+       temp = div_s64(temp, BIT(16));
+       temp = (temp - param->B) * 100;
+
+       return temp;
+}
+
+static int amlogic_thermal_initialize(struct amlogic_thermal *pdata)
+{
+       int ret = 0;
+       int ver;
+
+       regmap_read(pdata->sec_ao_map, pdata->data->u_efuse_off,
+                   &pdata->trim_info);
+
+       ver = TSENSOR_TRIM_VERSION(pdata->trim_info);
+
+       if ((ver & TSENSOR_TRIM_CALIB_VALID_MASK) == 0) {
+               ret = -EINVAL;
+               dev_err(&pdata->pdev->dev,
+                       "tsensor thermal calibration not supported: 0x%x!\n",
+                       ver);
+       }
+
+       return ret;
+}
+
+static int amlogic_thermal_enable(struct amlogic_thermal *data)
+{
+       int ret;
+
+       ret = clk_prepare_enable(data->clk);
+       if (ret)
+               return ret;
+
+       regmap_update_bits(data->regmap, TSENSOR_CFG_REG1,
+                          TSENSOR_CFG_REG1_ENABLE, TSENSOR_CFG_REG1_ENABLE);
+
+       return 0;
+}
+
+static int amlogic_thermal_disable(struct amlogic_thermal *data)
+{
+       regmap_update_bits(data->regmap, TSENSOR_CFG_REG1,
+                          TSENSOR_CFG_REG1_ENABLE, 0);
+       clk_disable_unprepare(data->clk);
+
+       return 0;
+}
+
+static int amlogic_thermal_get_temp(void *data, int *temp)
+{
+       unsigned int tval;
+       struct amlogic_thermal *pdata = data;
+
+       if (!data)
+               return -EINVAL;
+
+       regmap_read(pdata->regmap, TSENSOR_STAT0, &tval);
+       *temp =
+          amlogic_thermal_code_to_millicelsius(pdata,
+                                               tval & TSENSOR_READ_TEMP_MASK);
+
+       return 0;
+}
+
+static const struct thermal_zone_of_device_ops amlogic_thermal_ops = {
+       .get_temp       = amlogic_thermal_get_temp,
+};
+
+static const struct regmap_config amlogic_thermal_regmap_config_g12a = {
+       .reg_bits = 8,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .max_register = TSENSOR_STAT9,
+};
+
+static const struct amlogic_thermal_soc_calib_data amlogic_thermal_g12a = {
+       .A = 9411,
+       .B = 3159,
+       .m = 424,
+       .n = 324,
+};
+
+static const struct amlogic_thermal_data amlogic_thermal_g12a_cpu_param = {
+       .u_efuse_off = 0x128,
+       .calibration_parameters = &amlogic_thermal_g12a,
+       .regmap_config = &amlogic_thermal_regmap_config_g12a,
+};
+
+static const struct amlogic_thermal_data amlogic_thermal_g12a_ddr_param = {
+       .u_efuse_off = 0xf0,
+       .calibration_parameters = &amlogic_thermal_g12a,
+       .regmap_config = &amlogic_thermal_regmap_config_g12a,
+};
+
+static const struct of_device_id of_amlogic_thermal_match[] = {
+       {
+               .compatible = "amlogic,g12a-ddr-thermal",
+               .data = &amlogic_thermal_g12a_ddr_param,
+       },
+       {
+               .compatible = "amlogic,g12a-cpu-thermal",
+               .data = &amlogic_thermal_g12a_cpu_param,
+       },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, of_amlogic_thermal_match);
+
+static int amlogic_thermal_probe(struct platform_device *pdev)
+{
+       struct amlogic_thermal *pdata;
+       struct device *dev = &pdev->dev;
+       void __iomem *base;
+       int ret;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       pdata->data = of_device_get_match_data(dev);
+       pdata->pdev = pdev;
+       platform_set_drvdata(pdev, pdata);
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base)) {
+               dev_err(dev, "failed to get io address\n");
+               return PTR_ERR(base);
+       }
+
+       pdata->regmap = devm_regmap_init_mmio(dev, base,
+                                             pdata->data->regmap_config);
+       if (IS_ERR(pdata->regmap))
+               return PTR_ERR(pdata->regmap);
+
+       pdata->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(pdata->clk)) {
+               if (PTR_ERR(pdata->clk) != -EPROBE_DEFER)
+                       dev_err(dev, "failed to get clock\n");
+               return PTR_ERR(pdata->clk);
+       }
+
+       pdata->sec_ao_map = syscon_regmap_lookup_by_phandle
+               (pdev->dev.of_node, "amlogic,ao-secure");
+       if (IS_ERR(pdata->sec_ao_map)) {
+               dev_err(dev, "syscon regmap lookup failed.\n");
+               return PTR_ERR(pdata->sec_ao_map);
+       }
+
+       pdata->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev,
+                                                         0,
+                                                         pdata,
+                                                         &amlogic_thermal_ops);
+       if (IS_ERR(pdata->tzd)) {
+               ret = PTR_ERR(pdata->tzd);
+               dev_err(dev, "Failed to register tsensor: %d\n", ret);
+               return ret;
+       }
+
+       ret = amlogic_thermal_initialize(pdata);
+       if (ret)
+               return ret;
+
+       ret = amlogic_thermal_enable(pdata);
+
+       return ret;
+}
+
+static int amlogic_thermal_remove(struct platform_device *pdev)
+{
+       struct amlogic_thermal *data = platform_get_drvdata(pdev);
+
+       return amlogic_thermal_disable(data);
+}
+
+static int __maybe_unused amlogic_thermal_suspend(struct device *dev)
+{
+       struct amlogic_thermal *data = dev_get_drvdata(dev);
+
+       return amlogic_thermal_disable(data);
+}
+
+static int __maybe_unused amlogic_thermal_resume(struct device *dev)
+{
+       struct amlogic_thermal *data = dev_get_drvdata(dev);
+
+       return amlogic_thermal_enable(data);
+}
+
+static SIMPLE_DEV_PM_OPS(amlogic_thermal_pm_ops,
+                        amlogic_thermal_suspend, amlogic_thermal_resume);
+
+static struct platform_driver amlogic_thermal_driver = {
+       .driver = {
+               .name           = "amlogic_thermal",
+               .pm             = &amlogic_thermal_pm_ops,
+               .of_match_table = of_amlogic_thermal_match,
+       },
+       .probe  = amlogic_thermal_probe,
+       .remove = amlogic_thermal_remove,
+};
+
+module_platform_driver(amlogic_thermal_driver);
+
+MODULE_AUTHOR("Guillaume La Roque <glaroque@baylibre.com>");
+MODULE_DESCRIPTION("Amlogic thermal driver");
+MODULE_LICENSE("GPL v2");
index 6b9865c..52569b2 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/cpu_cooling.h>
+#include <linux/energy_model.h>
 
 #include <trace/events/thermal.h>
 
  */
 
 /**
- * struct freq_table - frequency table along with power entries
- * @frequency: frequency in KHz
- * @power:     power in mW
- *
- * This structure is built when the cooling device registers and helps
- * in translating frequency to power and vice versa.
- */
-struct freq_table {
-       u32 frequency;
-       u32 power;
-};
-
-/**
  * struct time_in_idle - Idle time stats
  * @time: previous reading of the absolute time that this cpu was idle
  * @timestamp: wall time of the last invocation of get_cpu_idle_time_us()
@@ -69,7 +57,7 @@ struct time_in_idle {
  *     cooling devices.
  * @max_level: maximum cooling level. One less than total number of valid
  *     cpufreq frequencies.
- * @freq_table: Freq table in descending order of frequencies
+ * @em: Reference on the Energy Model of the device
  * @cdev: thermal_cooling_device pointer to keep track of the
  *     registered cooling device.
  * @policy: cpufreq policy.
@@ -84,7 +72,7 @@ struct cpufreq_cooling_device {
        u32 last_load;
        unsigned int cpufreq_state;
        unsigned int max_level;
-       struct freq_table *freq_table;  /* In descending order */
+       struct em_perf_domain *em;
        struct cpufreq_policy *policy;
        struct list_head node;
        struct time_in_idle *idle_time;
@@ -95,8 +83,7 @@ static DEFINE_IDA(cpufreq_ida);
 static DEFINE_MUTEX(cooling_list_lock);
 static LIST_HEAD(cpufreq_cdev_list);
 
-/* Below code defines functions to be used for cpufreq as cooling device */
-
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
 /**
  * get_level: Find the level for a particular frequency
  * @cpufreq_cdev: cpufreq_cdev for which the property is required
@@ -107,114 +94,40 @@ static LIST_HEAD(cpufreq_cdev_list);
 static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev,
                               unsigned int freq)
 {
-       struct freq_table *freq_table = cpufreq_cdev->freq_table;
-       unsigned long level;
+       int i;
 
-       for (level = 1; level <= cpufreq_cdev->max_level; level++)
-               if (freq > freq_table[level].frequency)
+       for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
+               if (freq > cpufreq_cdev->em->table[i].frequency)
                        break;
-
-       return level - 1;
-}
-
-/**
- * update_freq_table() - Update the freq table with power numbers
- * @cpufreq_cdev:      the cpufreq cooling device in which to update the table
- * @capacitance: dynamic power coefficient for these cpus
- *
- * Update the freq table with power numbers.  This table will be used in
- * cpu_power_to_freq() and cpu_freq_to_power() to convert between power and
- * frequency efficiently.  Power is stored in mW, frequency in KHz.  The
- * resulting table is in descending order.
- *
- * Return: 0 on success, -EINVAL if there are no OPPs for any CPUs,
- * or -ENOMEM if we run out of memory.
- */
-static int update_freq_table(struct cpufreq_cooling_device *cpufreq_cdev,
-                            u32 capacitance)
-{
-       struct freq_table *freq_table = cpufreq_cdev->freq_table;
-       struct dev_pm_opp *opp;
-       struct device *dev = NULL;
-       int num_opps = 0, cpu = cpufreq_cdev->policy->cpu, i;
-
-       dev = get_cpu_device(cpu);
-       if (unlikely(!dev)) {
-               pr_warn("No cpu device for cpu %d\n", cpu);
-               return -ENODEV;
        }
 
-       num_opps = dev_pm_opp_get_opp_count(dev);
-       if (num_opps < 0)
-               return num_opps;
-
-       /*
-        * The cpufreq table is also built from the OPP table and so the count
-        * should match.
-        */
-       if (num_opps != cpufreq_cdev->max_level + 1) {
-               dev_warn(dev, "Number of OPPs not matching with max_levels\n");
-               return -EINVAL;
-       }
-
-       for (i = 0; i <= cpufreq_cdev->max_level; i++) {
-               unsigned long freq = freq_table[i].frequency * 1000;
-               u32 freq_mhz = freq_table[i].frequency / 1000;
-               u64 power;
-               u32 voltage_mv;
-
-               /*
-                * Find ceil frequency as 'freq' may be slightly lower than OPP
-                * freq due to truncation while converting to kHz.
-                */
-               opp = dev_pm_opp_find_freq_ceil(dev, &freq);
-               if (IS_ERR(opp)) {
-                       dev_err(dev, "failed to get opp for %lu frequency\n",
-                               freq);
-                       return -EINVAL;
-               }
-
-               voltage_mv = dev_pm_opp_get_voltage(opp) / 1000;
-               dev_pm_opp_put(opp);
-
-               /*
-                * Do the multiplication with MHz and millivolt so as
-                * to not overflow.
-                */
-               power = (u64)capacitance * freq_mhz * voltage_mv * voltage_mv;
-               do_div(power, 1000000000);
-
-               /* power is stored in mW */
-               freq_table[i].power = power;
-       }
-
-       return 0;
+       return cpufreq_cdev->max_level - i - 1;
 }
 
 static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_cdev,
                             u32 freq)
 {
        int i;
-       struct freq_table *freq_table = cpufreq_cdev->freq_table;
 
-       for (i = 1; i <= cpufreq_cdev->max_level; i++)
-               if (freq > freq_table[i].frequency)
+       for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
+               if (freq > cpufreq_cdev->em->table[i].frequency)
                        break;
+       }
 
-       return freq_table[i - 1].power;
+       return cpufreq_cdev->em->table[i + 1].power;
 }
 
 static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
                             u32 power)
 {
        int i;
-       struct freq_table *freq_table = cpufreq_cdev->freq_table;
 
-       for (i = 1; i <= cpufreq_cdev->max_level; i++)
-               if (power > freq_table[i].power)
+       for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
+               if (power > cpufreq_cdev->em->table[i].power)
                        break;
+       }
 
-       return freq_table[i - 1].frequency;
+       return cpufreq_cdev->em->table[i + 1].frequency;
 }
 
 /**
@@ -265,76 +178,6 @@ static u32 get_dynamic_power(struct cpufreq_cooling_device *cpufreq_cdev,
        return (raw_cpu_power * cpufreq_cdev->last_load) / 100;
 }
 
-/* cpufreq cooling device callback functions are defined below */
-
-/**
- * cpufreq_get_max_state - callback function to get the max cooling state.
- * @cdev: thermal cooling device pointer.
- * @state: fill this variable with the max cooling state.
- *
- * Callback for the thermal cooling device to return the cpufreq
- * max cooling state.
- *
- * Return: 0 on success, an error code otherwise.
- */
-static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
-                                unsigned long *state)
-{
-       struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
-
-       *state = cpufreq_cdev->max_level;
-       return 0;
-}
-
-/**
- * cpufreq_get_cur_state - callback function to get the current cooling state.
- * @cdev: thermal cooling device pointer.
- * @state: fill this variable with the current cooling state.
- *
- * Callback for the thermal cooling device to return the cpufreq
- * current cooling state.
- *
- * Return: 0 on success, an error code otherwise.
- */
-static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
-                                unsigned long *state)
-{
-       struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
-
-       *state = cpufreq_cdev->cpufreq_state;
-
-       return 0;
-}
-
-/**
- * cpufreq_set_cur_state - callback function to set the current cooling state.
- * @cdev: thermal cooling device pointer.
- * @state: set this variable to the current cooling state.
- *
- * Callback for the thermal cooling device to change the cpufreq
- * current cooling state.
- *
- * Return: 0 on success, an error code otherwise.
- */
-static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
-                                unsigned long state)
-{
-       struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
-
-       /* Request state should be less than max_level */
-       if (WARN_ON(state > cpufreq_cdev->max_level))
-               return -EINVAL;
-
-       /* Check if the old cooling action is same as new cooling action */
-       if (cpufreq_cdev->cpufreq_state == state)
-               return 0;
-
-       cpufreq_cdev->cpufreq_state = state;
-
-       return freq_qos_update_request(&cpufreq_cdev->qos_req,
-                               cpufreq_cdev->freq_table[state].frequency);
-}
-
 /**
  * cpufreq_get_requested_power() - get the current power
  * @cdev:      &thermal_cooling_device pointer
@@ -425,7 +268,7 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
                               struct thermal_zone_device *tz,
                               unsigned long state, u32 *power)
 {
-       unsigned int freq, num_cpus;
+       unsigned int freq, num_cpus, idx;
        struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
 
        /* Request state should be less than max_level */
@@ -434,7 +277,8 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
 
        num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus);
 
-       freq = cpufreq_cdev->freq_table[state].frequency;
+       idx = cpufreq_cdev->max_level - state;
+       freq = cpufreq_cdev->em->table[idx].frequency;
        *power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus;
 
        return 0;
@@ -479,43 +323,142 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
        return 0;
 }
 
-/* Bind cpufreq callbacks to thermal cooling device ops */
+static inline bool em_is_sane(struct cpufreq_cooling_device *cpufreq_cdev,
+                             struct em_perf_domain *em) {
+       struct cpufreq_policy *policy;
+       unsigned int nr_levels;
 
-static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
-       .get_max_state = cpufreq_get_max_state,
-       .get_cur_state = cpufreq_get_cur_state,
-       .set_cur_state = cpufreq_set_cur_state,
-};
+       if (!em)
+               return false;
 
-static struct thermal_cooling_device_ops cpufreq_power_cooling_ops = {
-       .get_max_state          = cpufreq_get_max_state,
-       .get_cur_state          = cpufreq_get_cur_state,
-       .set_cur_state          = cpufreq_set_cur_state,
-       .get_requested_power    = cpufreq_get_requested_power,
-       .state2power            = cpufreq_state2power,
-       .power2state            = cpufreq_power2state,
-};
+       policy = cpufreq_cdev->policy;
+       if (!cpumask_equal(policy->related_cpus, to_cpumask(em->cpus))) {
+               pr_err("The span of pd %*pbl is misaligned with cpufreq policy %*pbl\n",
+                       cpumask_pr_args(to_cpumask(em->cpus)),
+                       cpumask_pr_args(policy->related_cpus));
+               return false;
+       }
 
-static unsigned int find_next_max(struct cpufreq_frequency_table *table,
-                                 unsigned int prev_max)
+       nr_levels = cpufreq_cdev->max_level + 1;
+       if (em->nr_cap_states != nr_levels) {
+               pr_err("The number of cap states in pd %*pbl (%u) doesn't match the number of cooling levels (%u)\n",
+                       cpumask_pr_args(to_cpumask(em->cpus)),
+                       em->nr_cap_states, nr_levels);
+               return false;
+       }
+
+       return true;
+}
+#endif /* CONFIG_THERMAL_GOV_POWER_ALLOCATOR */
+
+static unsigned int get_state_freq(struct cpufreq_cooling_device *cpufreq_cdev,
+                                  unsigned long state)
 {
-       struct cpufreq_frequency_table *pos;
-       unsigned int max = 0;
+       struct cpufreq_policy *policy;
+       unsigned long idx;
 
-       cpufreq_for_each_valid_entry(pos, table) {
-               if (pos->frequency > max && pos->frequency < prev_max)
-                       max = pos->frequency;
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
+       /* Use the Energy Model table if available */
+       if (cpufreq_cdev->em) {
+               idx = cpufreq_cdev->max_level - state;
+               return cpufreq_cdev->em->table[idx].frequency;
        }
+#endif
+
+       /* Otherwise, fallback on the CPUFreq table */
+       policy = cpufreq_cdev->policy;
+       if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING)
+               idx = cpufreq_cdev->max_level - state;
+       else
+               idx = state;
+
+       return policy->freq_table[idx].frequency;
+}
+
+/* cpufreq cooling device callback functions are defined below */
+
+/**
+ * cpufreq_get_max_state - callback function to get the max cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: fill this variable with the max cooling state.
+ *
+ * Callback for the thermal cooling device to return the cpufreq
+ * max cooling state.
+ *
+ * Return: 0 on success, an error code otherwise.
+ */
+static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
+                                unsigned long *state)
+{
+       struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
+
+       *state = cpufreq_cdev->max_level;
+       return 0;
+}
+
+/**
+ * cpufreq_get_cur_state - callback function to get the current cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: fill this variable with the current cooling state.
+ *
+ * Callback for the thermal cooling device to return the cpufreq
+ * current cooling state.
+ *
+ * Return: 0 on success, an error code otherwise.
+ */
+static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
+                                unsigned long *state)
+{
+       struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
 
-       return max;
+       *state = cpufreq_cdev->cpufreq_state;
+
+       return 0;
 }
 
 /**
+ * cpufreq_set_cur_state - callback function to set the current cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: set this variable to the current cooling state.
+ *
+ * Callback for the thermal cooling device to change the cpufreq
+ * current cooling state.
+ *
+ * Return: 0 on success, an error code otherwise.
+ */
+static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
+                                unsigned long state)
+{
+       struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
+
+       /* Request state should be less than max_level */
+       if (WARN_ON(state > cpufreq_cdev->max_level))
+               return -EINVAL;
+
+       /* Check if the old cooling action is same as new cooling action */
+       if (cpufreq_cdev->cpufreq_state == state)
+               return 0;
+
+       cpufreq_cdev->cpufreq_state = state;
+
+       return freq_qos_update_request(&cpufreq_cdev->qos_req,
+                               get_state_freq(cpufreq_cdev, state));
+}
+
+/* Bind cpufreq callbacks to thermal cooling device ops */
+
+static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
+       .get_max_state          = cpufreq_get_max_state,
+       .get_cur_state          = cpufreq_get_cur_state,
+       .set_cur_state          = cpufreq_set_cur_state,
+};
+
+/**
  * __cpufreq_cooling_register - helper function to create cpufreq cooling device
  * @np: a valid struct device_node to the cooling device device tree node
  * @policy: cpufreq policy
  * Normally this should be same as cpufreq policy->related_cpus.
- * @capacitance: dynamic power coefficient for these cpus
+ * @em: Energy Model of the cpufreq policy
  *
  * This interface function registers the cpufreq cooling device with the name
  * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
@@ -527,12 +470,13 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
  */
 static struct thermal_cooling_device *
 __cpufreq_cooling_register(struct device_node *np,
-                       struct cpufreq_policy *policy, u32 capacitance)
+                       struct cpufreq_policy *policy,
+                       struct em_perf_domain *em)
 {
        struct thermal_cooling_device *cdev;
        struct cpufreq_cooling_device *cpufreq_cdev;
        char dev_name[THERMAL_NAME_LENGTH];
-       unsigned int freq, i, num_cpus;
+       unsigned int i, num_cpus;
        struct device *dev;
        int ret;
        struct thermal_cooling_device_ops *cooling_ops;
@@ -573,51 +517,36 @@ __cpufreq_cooling_register(struct device_node *np,
        /* max_level is an index, not a counter */
        cpufreq_cdev->max_level = i - 1;
 
-       cpufreq_cdev->freq_table = kmalloc_array(i,
-                                       sizeof(*cpufreq_cdev->freq_table),
-                                       GFP_KERNEL);
-       if (!cpufreq_cdev->freq_table) {
-               cdev = ERR_PTR(-ENOMEM);
-               goto free_idle_time;
-       }
-
        ret = ida_simple_get(&cpufreq_ida, 0, 0, GFP_KERNEL);
        if (ret < 0) {
                cdev = ERR_PTR(ret);
-               goto free_table;
+               goto free_idle_time;
        }
        cpufreq_cdev->id = ret;
 
        snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
                 cpufreq_cdev->id);
 
-       /* Fill freq-table in descending order of frequencies */
-       for (i = 0, freq = -1; i <= cpufreq_cdev->max_level; i++) {
-               freq = find_next_max(policy->freq_table, freq);
-               cpufreq_cdev->freq_table[i].frequency = freq;
-
-               /* Warn for duplicate entries */
-               if (!freq)
-                       pr_warn("%s: table has duplicate entries\n", __func__);
-               else
-                       pr_debug("%s: freq:%u KHz\n", __func__, freq);
-       }
-
-       if (capacitance) {
-               ret = update_freq_table(cpufreq_cdev, capacitance);
-               if (ret) {
-                       cdev = ERR_PTR(ret);
-                       goto remove_ida;
-               }
-
-               cooling_ops = &cpufreq_power_cooling_ops;
-       } else {
-               cooling_ops = &cpufreq_cooling_ops;
+       cooling_ops = &cpufreq_cooling_ops;
+
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
+       if (em_is_sane(cpufreq_cdev, em)) {
+               cpufreq_cdev->em = em;
+               cooling_ops->get_requested_power = cpufreq_get_requested_power;
+               cooling_ops->state2power = cpufreq_state2power;
+               cooling_ops->power2state = cpufreq_power2state;
+       } else
+#endif
+       if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) {
+               pr_err("%s: unsorted frequency tables are not supported\n",
+                      __func__);
+               cdev = ERR_PTR(-EINVAL);
+               goto remove_ida;
        }
 
        ret = freq_qos_add_request(&policy->constraints,
                                   &cpufreq_cdev->qos_req, FREQ_QOS_MAX,
-                                  cpufreq_cdev->freq_table[0].frequency);
+                                  get_state_freq(cpufreq_cdev, 0));
        if (ret < 0) {
                pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
                       ret);
@@ -640,8 +569,6 @@ remove_qos_req:
        freq_qos_remove_request(&cpufreq_cdev->qos_req);
 remove_ida:
        ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
-free_table:
-       kfree(cpufreq_cdev->freq_table);
 free_idle_time:
        kfree(cpufreq_cdev->idle_time);
 free_cdev:
@@ -663,7 +590,7 @@ free_cdev:
 struct thermal_cooling_device *
 cpufreq_cooling_register(struct cpufreq_policy *policy)
 {
-       return __cpufreq_cooling_register(NULL, policy, 0);
+       return __cpufreq_cooling_register(NULL, policy, NULL);
 }
 EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
 
@@ -691,7 +618,6 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy)
 {
        struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
        struct thermal_cooling_device *cdev = NULL;
-       u32 capacitance = 0;
 
        if (!np) {
                pr_err("cpu_cooling: OF node not available for cpu%d\n",
@@ -700,10 +626,9 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy)
        }
 
        if (of_find_property(np, "#cooling-cells", NULL)) {
-               of_property_read_u32(np, "dynamic-power-coefficient",
-                                    &capacitance);
+               struct em_perf_domain *em = em_cpu_get(policy->cpu);
 
-               cdev = __cpufreq_cooling_register(np, policy, capacitance);
+               cdev = __cpufreq_cooling_register(np, policy, em);
                if (IS_ERR(cdev)) {
                        pr_err("cpu_cooling: cpu%d failed to register as cooling device: %ld\n",
                               policy->cpu, PTR_ERR(cdev));
@@ -739,7 +664,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
        freq_qos_remove_request(&cpufreq_cdev->qos_req);
        ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
        kfree(cpufreq_cdev->idle_time);
-       kfree(cpufreq_cdev->freq_table);
        kfree(cpufreq_cdev);
 }
 EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister);
index 5716b62..f75271b 100644 (file)
@@ -6,6 +6,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
@@ -103,6 +104,7 @@ static int update_trip_temp(struct intel_soc_dts_sensor_entry *dts,
        int status;
        u32 temp_out;
        u32 out;
+       unsigned long update_ptps;
        u32 store_ptps;
        u32 store_ptmc;
        u32 store_te_out;
@@ -120,8 +122,10 @@ static int update_trip_temp(struct intel_soc_dts_sensor_entry *dts,
        if (status)
                return status;
 
-       out = (store_ptps & ~(0xFF << (thres_index * 8)));
-       out |= (temp_out & 0xFF) << (thres_index * 8);
+       update_ptps = store_ptps;
+       bitmap_set_value8(&update_ptps, temp_out & 0xFF, thres_index * 8);
+       out = update_ptps;
+
        status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
                                SOC_DTS_OFFSET_PTPS, out);
        if (status)
@@ -223,6 +227,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd,
        u32 out;
        struct intel_soc_dts_sensor_entry *dts;
        struct intel_soc_dts_sensors *sensors;
+       unsigned long raw;
 
        dts = tzd->devdata;
        sensors = dts->sensors;
@@ -231,8 +236,8 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd,
        if (status)
                return status;
 
-       out = (out & dts->temp_mask) >> dts->temp_shift;
-       out -= SOC_DTS_TJMAX_ENCODING;
+       raw = out;
+       out = bitmap_get_value8(&raw, dts->id * 8) - SOC_DTS_TJMAX_ENCODING;
        *temp = sensors->tj_max - out * 1000;
 
        return 0;
@@ -280,11 +285,14 @@ static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
                                int read_only_trip_cnt)
 {
        char name[10];
+       unsigned long trip;
        int trip_count = 0;
        int trip_mask = 0;
+       int writable_trip_cnt = 0;
+       unsigned long ptps;
        u32 store_ptps;
+       unsigned long i;
        int ret;
-       int i;
 
        /* Store status to restor on exit */
        ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
@@ -293,11 +301,10 @@ static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
                goto err_ret;
 
        dts->id = id;
-       dts->temp_mask = 0x00FF << (id * 8);
-       dts->temp_shift = id * 8;
        if (notification_support) {
                trip_count = min(SOC_MAX_DTS_TRIPS, trip_cnt);
-               trip_mask = BIT(trip_count - read_only_trip_cnt) - 1;
+               writable_trip_cnt = trip_count - read_only_trip_cnt;
+               trip_mask = GENMASK(writable_trip_cnt - 1, 0);
        }
 
        /* Check if the writable trip we provide is not used by BIOS */
@@ -306,11 +313,9 @@ static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
        if (ret)
                trip_mask = 0;
        else {
-               for (i = 0; i < trip_count; ++i) {
-                       if (trip_mask & BIT(i))
-                               if (store_ptps & (0xff << (i * 8)))
-                                       trip_mask &= ~BIT(i);
-               }
+               ptps = store_ptps;
+               for_each_set_clump8(i, trip, &ptps, writable_trip_cnt * 8)
+                       trip_mask &= ~BIT(i / 8);
        }
        dts->trip_mask = trip_mask;
        dts->trip_count = trip_count;
index adfb09a..c549457 100644 (file)
@@ -24,8 +24,6 @@ struct intel_soc_dts_sensors;
 
 struct intel_soc_dts_sensor_entry {
        int id;
-       u32 temp_mask;
-       u32 temp_shift;
        u32 store_status;
        u32 trip_mask;
        u32 trip_count;
index e46a4e3..fb77acb 100644 (file)
@@ -245,11 +245,11 @@ static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
        return adc_code * slope + offset;
 }
 
-static int get_temp_8960(struct tsens_priv *priv, int id, int *temp)
+static int get_temp_8960(struct tsens_sensor *s, int *temp)
 {
        int ret;
        u32 code, trdy;
-       const struct tsens_sensor *s = &priv->sensor[id];
+       struct tsens_priv *priv = s->priv;
        unsigned long timeout;
 
        timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
index 528df88..c8d57ee 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/debugfs.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/regmap.h>
 #include "tsens.h"
 
+/**
+ * struct tsens_irq_data - IRQ status and temperature violations
+ * @up_viol:        upper threshold violated
+ * @up_thresh:      upper threshold temperature value
+ * @up_irq_mask:    mask register for upper threshold irqs
+ * @up_irq_clear:   clear register for uppper threshold irqs
+ * @low_viol:       lower threshold violated
+ * @low_thresh:     lower threshold temperature value
+ * @low_irq_mask:   mask register for lower threshold irqs
+ * @low_irq_clear:  clear register for lower threshold irqs
+ *
+ * Structure containing data about temperature threshold settings and
+ * irq status if they were violated.
+ */
+struct tsens_irq_data {
+       u32 up_viol;
+       int up_thresh;
+       u32 up_irq_mask;
+       u32 up_irq_clear;
+       u32 low_viol;
+       int low_thresh;
+       u32 low_irq_mask;
+       u32 low_irq_clear;
+};
+
 char *qfprom_read(struct device *dev, const char *cname)
 {
        struct nvmem_cell *cell;
@@ -42,8 +68,8 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
 
        for (i = 0; i < priv->num_sensors; i++) {
                dev_dbg(priv->dev,
-                       "sensor%d - data_point1:%#x data_point2:%#x\n",
-                       i, p1[i], p2[i]);
+                       "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
+                       __func__, i, p1[i], p2[i]);
 
                priv->sensor[i].slope = SLOPE_DEFAULT;
                if (mode == TWO_PT_CALIB) {
@@ -60,10 +86,18 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
                priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
                                (CAL_DEGC_PT1 *
                                priv->sensor[i].slope);
-               dev_dbg(priv->dev, "offset:%d\n", priv->sensor[i].offset);
+               dev_dbg(priv->dev, "%s: offset:%d\n", __func__, priv->sensor[i].offset);
        }
 }
 
+static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)
+{
+       u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);
+
+       pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);
+       return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);
+}
+
 static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
 {
        int degc, num, den;
@@ -83,12 +117,353 @@ static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
        return degc;
 }
 
-int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp)
+/**
+ * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.
+ * @s:     Pointer to sensor struct
+ * @field: Index into regmap_field array pointing to temperature data
+ *
+ * This function handles temperature returned in ADC code or deciCelsius
+ * depending on IP version.
+ *
+ * Return: Temperature in milliCelsius on success, a negative errno will
+ * be returned in error cases
+ */
+static int tsens_hw_to_mC(struct tsens_sensor *s, int field)
+{
+       struct tsens_priv *priv = s->priv;
+       u32 resolution;
+       u32 temp = 0;
+       int ret;
+
+       resolution = priv->fields[LAST_TEMP_0].msb -
+               priv->fields[LAST_TEMP_0].lsb;
+
+       ret = regmap_field_read(priv->rf[field], &temp);
+       if (ret)
+               return ret;
+
+       /* Convert temperature from ADC code to milliCelsius */
+       if (priv->feat->adc)
+               return code_to_degc(temp, s) * 1000;
+
+       /* deciCelsius -> milliCelsius along with sign extension */
+       return sign_extend32(temp, resolution) * 100;
+}
+
+/**
+ * tsens_mC_to_hw - Convert temperature to hardware register value
+ * @s: Pointer to sensor struct
+ * @temp: temperature in milliCelsius to be programmed to hardware
+ *
+ * This function outputs the value to be written to hardware in ADC code
+ * or deciCelsius depending on IP version.
+ *
+ * Return: ADC code or temperature in deciCelsius.
+ */
+static int tsens_mC_to_hw(struct tsens_sensor *s, int temp)
+{
+       struct tsens_priv *priv = s->priv;
+
+       /* milliC to adc code */
+       if (priv->feat->adc)
+               return degc_to_code(temp / 1000, s);
+
+       /* milliC to deciC */
+       return temp / 100;
+}
+
+static inline enum tsens_ver tsens_version(struct tsens_priv *priv)
+{
+       return priv->feat->ver_major;
+}
+
+static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,
+                                  enum tsens_irq_type irq_type, bool enable)
+{
+       u32 index = 0;
+
+       switch (irq_type) {
+       case UPPER:
+               index = UP_INT_CLEAR_0 + hw_id;
+               break;
+       case LOWER:
+               index = LOW_INT_CLEAR_0 + hw_id;
+               break;
+       }
+       regmap_field_write(priv->rf[index], enable ? 0 : 1);
+}
+
+static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,
+                                  enum tsens_irq_type irq_type, bool enable)
+{
+       u32 index_mask = 0, index_clear = 0;
+
+       /*
+        * To enable the interrupt flag for a sensor:
+        *    - clear the mask bit
+        * To disable the interrupt flag for a sensor:
+        *    - Mask further interrupts for this sensor
+        *    - Write 1 followed by 0 to clear the interrupt
+        */
+       switch (irq_type) {
+       case UPPER:
+               index_mask  = UP_INT_MASK_0 + hw_id;
+               index_clear = UP_INT_CLEAR_0 + hw_id;
+               break;
+       case LOWER:
+               index_mask  = LOW_INT_MASK_0 + hw_id;
+               index_clear = LOW_INT_CLEAR_0 + hw_id;
+               break;
+       }
+
+       if (enable) {
+               regmap_field_write(priv->rf[index_mask], 0);
+       } else {
+               regmap_field_write(priv->rf[index_mask],  1);
+               regmap_field_write(priv->rf[index_clear], 1);
+               regmap_field_write(priv->rf[index_clear], 0);
+       }
+}
+
+/**
+ * tsens_set_interrupt - Set state of an interrupt
+ * @priv: Pointer to tsens controller private data
+ * @hw_id: Hardware ID aka. sensor number
+ * @irq_type: irq_type from enum tsens_irq_type
+ * @enable: false = disable, true = enable
+ *
+ * Call IP-specific function to set state of an interrupt
+ *
+ * Return: void
+ */
+static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
+                               enum tsens_irq_type irq_type, bool enable)
+{
+       dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
+               irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
+               enable ? "en" : "dis");
+       if (tsens_version(priv) > VER_1_X)
+               tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
+       else
+               tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
+}
+
+/**
+ * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold
+ * @priv: Pointer to tsens controller private data
+ * @hw_id: Hardware ID aka. sensor number
+ * @d: Pointer to irq state data
+ *
+ * Return: 0 if threshold was not violated, 1 if it was violated and negative
+ * errno in case of errors
+ */
+static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,
+                                   struct tsens_irq_data *d)
 {
-       struct tsens_sensor *s = &priv->sensor[i];
-       u32 temp_idx = LAST_TEMP_0 + s->hw_id;
-       u32 valid_idx = VALID_0 + s->hw_id;
-       u32 last_temp = 0, valid, mask;
+       int ret;
+
+       ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);
+       if (ret)
+               return ret;
+       ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);
+       if (ret)
+               return ret;
+       if (d->up_viol || d->low_viol)
+               return 1;
+
+       return 0;
+}
+
+static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
+                               struct tsens_sensor *s, struct tsens_irq_data *d)
+{
+       int ret;
+
+       ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);
+       if (ret)
+               return ret;
+       ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
+       if (ret)
+               return ret;
+       if (tsens_version(priv) > VER_1_X) {
+               ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
+               if (ret)
+                       return ret;
+               ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);
+               if (ret)
+                       return ret;
+       } else {
+               /* No mask register on older TSENS */
+               d->up_irq_mask = 0;
+               d->low_irq_mask = 0;
+       }
+
+       d->up_thresh  = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);
+       d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);
+
+       dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u) | clr(%u|%u) | mask(%u|%u)\n",
+               hw_id, __func__, (d->up_viol || d->low_viol) ? "(V)" : "",
+               d->low_viol, d->up_viol, d->low_irq_clear, d->up_irq_clear,
+               d->low_irq_mask, d->up_irq_mask);
+       dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d)\n", hw_id, __func__,
+               (d->up_viol || d->low_viol) ? "(violation)" : "",
+               d->low_thresh, d->up_thresh);
+
+       return 0;
+}
+
+static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
+{
+       if (ver > VER_1_X)
+               return mask & (1 << hw_id);
+
+       /* v1, v0.1 don't have a irq mask register */
+       return 0;
+}
+
+/**
+ * tsens_irq_thread - Threaded interrupt handler for uplow interrupts
+ * @irq: irq number
+ * @data: tsens controller private data
+ *
+ * Check all sensors to find ones that violated their threshold limits. If the
+ * temperature is still outside the limits, call thermal_zone_device_update() to
+ * update the thresholds, else re-enable the interrupts.
+ *
+ * The level-triggered interrupt might deassert if the temperature returned to
+ * within the threshold limits by the time the handler got scheduled. We
+ * consider the irq to have been handled in that case.
+ *
+ * Return: IRQ_HANDLED
+ */
+irqreturn_t tsens_irq_thread(int irq, void *data)
+{
+       struct tsens_priv *priv = data;
+       struct tsens_irq_data d;
+       bool enable = true, disable = false;
+       unsigned long flags;
+       int temp, ret, i;
+
+       for (i = 0; i < priv->num_sensors; i++) {
+               bool trigger = false;
+               struct tsens_sensor *s = &priv->sensor[i];
+               u32 hw_id = s->hw_id;
+
+               if (IS_ERR(priv->sensor[i].tzd))
+                       continue;
+               if (!tsens_threshold_violated(priv, hw_id, &d))
+                       continue;
+               ret = get_temp_tsens_valid(s, &temp);
+               if (ret) {
+                       dev_err(priv->dev, "[%u] %s: error reading sensor\n", hw_id, __func__);
+                       continue;
+               }
+
+               spin_lock_irqsave(&priv->ul_lock, flags);
+
+               tsens_read_irq_state(priv, hw_id, s, &d);
+
+               if (d.up_viol &&
+                   !masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) {
+                       tsens_set_interrupt(priv, hw_id, UPPER, disable);
+                       if (d.up_thresh > temp) {
+                               dev_dbg(priv->dev, "[%u] %s: re-arm upper\n",
+                                       priv->sensor[i].hw_id, __func__);
+                               tsens_set_interrupt(priv, hw_id, UPPER, enable);
+                       } else {
+                               trigger = true;
+                               /* Keep irq masked */
+                       }
+               } else if (d.low_viol &&
+                          !masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) {
+                       tsens_set_interrupt(priv, hw_id, LOWER, disable);
+                       if (d.low_thresh < temp) {
+                               dev_dbg(priv->dev, "[%u] %s: re-arm low\n",
+                                       priv->sensor[i].hw_id, __func__);
+                               tsens_set_interrupt(priv, hw_id, LOWER, enable);
+                       } else {
+                               trigger = true;
+                               /* Keep irq masked */
+                       }
+               }
+
+               spin_unlock_irqrestore(&priv->ul_lock, flags);
+
+               if (trigger) {
+                       dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n",
+                               hw_id, __func__, temp);
+                       thermal_zone_device_update(priv->sensor[i].tzd,
+                                                  THERMAL_EVENT_UNSPECIFIED);
+               } else {
+                       dev_dbg(priv->dev, "[%u] %s: no violation:  %d\n",
+                               hw_id, __func__, temp);
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+int tsens_set_trips(void *_sensor, int low, int high)
+{
+       struct tsens_sensor *s = _sensor;
+       struct tsens_priv *priv = s->priv;
+       struct device *dev = priv->dev;
+       struct tsens_irq_data d;
+       unsigned long flags;
+       int high_val, low_val, cl_high, cl_low;
+       u32 hw_id = s->hw_id;
+
+       dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
+               hw_id, __func__, low, high);
+
+       cl_high = clamp_val(high, -40000, 120000);
+       cl_low  = clamp_val(low, -40000, 120000);
+
+       high_val = tsens_mC_to_hw(s, cl_high);
+       low_val  = tsens_mC_to_hw(s, cl_low);
+
+       spin_lock_irqsave(&priv->ul_lock, flags);
+
+       tsens_read_irq_state(priv, hw_id, s, &d);
+
+       /* Write the new thresholds and clear the status */
+       regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);
+       regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);
+       tsens_set_interrupt(priv, hw_id, LOWER, true);
+       tsens_set_interrupt(priv, hw_id, UPPER, true);
+
+       spin_unlock_irqrestore(&priv->ul_lock, flags);
+
+       dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",
+               s->hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);
+
+       return 0;
+}
+
+int tsens_enable_irq(struct tsens_priv *priv)
+{
+       int ret;
+       int val = tsens_version(priv) > VER_1_X ? 7 : 1;
+
+       ret = regmap_field_write(priv->rf[INT_EN], val);
+       if (ret < 0)
+               dev_err(priv->dev, "%s: failed to enable interrupts\n", __func__);
+
+       return ret;
+}
+
+void tsens_disable_irq(struct tsens_priv *priv)
+{
+       regmap_field_write(priv->rf[INT_EN], 0);
+}
+
+int get_temp_tsens_valid(struct tsens_sensor *s, int *temp)
+{
+       struct tsens_priv *priv = s->priv;
+       int hw_id = s->hw_id;
+       u32 temp_idx = LAST_TEMP_0 + hw_id;
+       u32 valid_idx = VALID_0 + hw_id;
+       u32 valid;
        int ret;
 
        ret = regmap_field_read(priv->rf[valid_idx], &valid);
@@ -106,29 +481,18 @@ int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp)
        }
 
        /* Valid bit is set, OK to read the temperature */
-       ret = regmap_field_read(priv->rf[temp_idx], &last_temp);
-       if (ret)
-               return ret;
-
-       if (priv->feat->adc) {
-               /* Convert temperature from ADC code to milliCelsius */
-               *temp = code_to_degc(last_temp, s) * 1000;
-       } else {
-               mask = GENMASK(priv->fields[LAST_TEMP_0].msb,
-                              priv->fields[LAST_TEMP_0].lsb);
-               /* Convert temperature from deciCelsius to milliCelsius */
-               *temp = sign_extend32(last_temp, fls(mask) - 1) * 100;
-       }
+       *temp = tsens_hw_to_mC(s, temp_idx);
 
        return 0;
 }
 
-int get_temp_common(struct tsens_priv *priv, int i, int *temp)
+int get_temp_common(struct tsens_sensor *s, int *temp)
 {
-       struct tsens_sensor *s = &priv->sensor[i];
+       struct tsens_priv *priv = s->priv;
+       int hw_id = s->hw_id;
        int last_temp = 0, ret;
 
-       ret = regmap_field_read(priv->rf[LAST_TEMP_0 + s->hw_id], &last_temp);
+       ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
        if (ret)
                return ret;
 
@@ -137,6 +501,77 @@ int get_temp_common(struct tsens_priv *priv, int i, int *temp)
        return 0;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static int dbg_sensors_show(struct seq_file *s, void *data)
+{
+       struct platform_device *pdev = s->private;
+       struct tsens_priv *priv = platform_get_drvdata(pdev);
+       int i;
+
+       seq_printf(s, "max: %2d\nnum: %2d\n\n",
+                  priv->feat->max_sensors, priv->num_sensors);
+
+       seq_puts(s, "      id    slope   offset\n--------------------------\n");
+       for (i = 0;  i < priv->num_sensors; i++) {
+               seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,
+                          priv->sensor[i].slope, priv->sensor[i].offset);
+       }
+
+       return 0;
+}
+
+static int dbg_version_show(struct seq_file *s, void *data)
+{
+       struct platform_device *pdev = s->private;
+       struct tsens_priv *priv = platform_get_drvdata(pdev);
+       u32 maj_ver, min_ver, step_ver;
+       int ret;
+
+       if (tsens_version(priv) > VER_0_1) {
+               ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);
+               if (ret)
+                       return ret;
+               ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);
+               if (ret)
+                       return ret;
+               ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);
+               if (ret)
+                       return ret;
+               seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
+       } else {
+               seq_puts(s, "0.1.0\n");
+       }
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(dbg_version);
+DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
+
+static void tsens_debug_init(struct platform_device *pdev)
+{
+       struct tsens_priv *priv = platform_get_drvdata(pdev);
+       struct dentry *root, *file;
+
+       root = debugfs_lookup("tsens", NULL);
+       if (!root)
+               priv->debug_root = debugfs_create_dir("tsens", NULL);
+       else
+               priv->debug_root = root;
+
+       file = debugfs_lookup("version", priv->debug_root);
+       if (!file)
+               debugfs_create_file("version", 0444, priv->debug_root,
+                                   pdev, &dbg_version_fops);
+
+       /* A directory for each instance of the TSENS IP */
+       priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
+       debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
+}
+#else
+static inline void tsens_debug_init(struct platform_device *pdev) {}
+#endif
+
 static const struct regmap_config tsens_config = {
        .name           = "tm",
        .reg_bits       = 32,
@@ -197,6 +632,15 @@ int __init init_common(struct tsens_priv *priv)
                goto err_put_device;
        }
 
+       if (tsens_version(priv) > VER_0_1) {
+               for (i = VER_MAJOR; i <= VER_STEP; i++) {
+                       priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
+                                                             priv->fields[i]);
+                       if (IS_ERR(priv->rf[i]))
+                               return PTR_ERR(priv->rf[i]);
+               }
+       }
+
        priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
                                                     priv->fields[TSENS_EN]);
        if (IS_ERR(priv->rf[TSENS_EN])) {
@@ -207,7 +651,7 @@ int __init init_common(struct tsens_priv *priv)
        if (ret)
                goto err_put_device;
        if (!enabled) {
-               dev_err(dev, "tsens device is not enabled\n");
+               dev_err(dev, "%s: device not enabled\n", __func__);
                ret = -ENODEV;
                goto err_put_device;
        }
@@ -218,24 +662,31 @@ int __init init_common(struct tsens_priv *priv)
                ret = PTR_ERR(priv->rf[SENSOR_EN]);
                goto err_put_device;
        }
-       /* now alloc regmap_fields in tm_map */
-       for (i = 0, j = LAST_TEMP_0; i < priv->feat->max_sensors; i++, j++) {
-               priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
-                                                     priv->fields[j]);
-               if (IS_ERR(priv->rf[j])) {
-                       ret = PTR_ERR(priv->rf[j]);
-                       goto err_put_device;
-               }
+       priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,
+                                                  priv->fields[INT_EN]);
+       if (IS_ERR(priv->rf[INT_EN])) {
+               ret = PTR_ERR(priv->rf[INT_EN]);
+               goto err_put_device;
        }
-       for (i = 0, j = VALID_0; i < priv->feat->max_sensors; i++, j++) {
-               priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
-                                                     priv->fields[j]);
-               if (IS_ERR(priv->rf[j])) {
-                       ret = PTR_ERR(priv->rf[j]);
-                       goto err_put_device;
+
+       /* This loop might need changes if enum regfield_ids is reordered */
+       for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
+               for (i = 0; i < priv->feat->max_sensors; i++) {
+                       int idx = j + i;
+
+                       priv->rf[idx] = devm_regmap_field_alloc(dev, priv->tm_map,
+                                                               priv->fields[idx]);
+                       if (IS_ERR(priv->rf[idx])) {
+                               ret = PTR_ERR(priv->rf[idx]);
+                               goto err_put_device;
+                       }
                }
        }
 
+       spin_lock_init(&priv->ul_lock);
+       tsens_enable_irq(priv);
+       tsens_debug_init(op);
+
        return 0;
 
 err_put_device:
index 055647b..4b8dd6d 100644 (file)
@@ -347,9 +347,20 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
        /* INTERRUPT ENABLE */
        [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
 
+       /* UPPER/LOWER TEMPERATURE THRESHOLDS */
+       REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH,    TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF,  0,  9),
+       REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH,     TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19),
+
+       /* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */
+       REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20),
+       REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR,  TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21),
+
+       /* NO CRITICAL INTERRUPT SUPPORT on v0.1 */
+
        /* Sn_STATUS */
        REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP,    TM_Sn_STATUS_OFF,  0,  9),
        /* No VALID field on v0.1 */
+       /* xxx_STATUS bits: 1 == threshold violated */
        REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS,   TM_Sn_STATUS_OFF, 10, 10),
        REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
        REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
index 870f502..bd2ddb6 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/bitops.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "tsens.h"
 
 /* ----- SROT ------ */
 #define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF      0x0004
 #define TM_Sn_STATUS_OFF                       0x0044
 #define TM_TRDY_OFF                            0x0084
+#define TM_HIGH_LOW_INT_STATUS_OFF             0x0088
+#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF       0x0090
+
+/* eeprom layout data for msm8956/76 (v1) */
+#define MSM8976_BASE0_MASK     0xff
+#define MSM8976_BASE1_MASK     0xff
+#define MSM8976_BASE1_SHIFT    8
+
+#define MSM8976_S0_P1_MASK     0x3f00
+#define MSM8976_S1_P1_MASK     0x3f00000
+#define MSM8976_S2_P1_MASK     0x3f
+#define MSM8976_S3_P1_MASK     0x3f000
+#define MSM8976_S4_P1_MASK     0x3f00
+#define MSM8976_S5_P1_MASK     0x3f00000
+#define MSM8976_S6_P1_MASK     0x3f
+#define MSM8976_S7_P1_MASK     0x3f000
+#define MSM8976_S8_P1_MASK     0x1f8
+#define MSM8976_S9_P1_MASK     0x1f8000
+#define MSM8976_S10_P1_MASK    0xf8000000
+#define MSM8976_S10_P1_MASK_1  0x1
+
+#define MSM8976_S0_P2_MASK     0xfc000
+#define MSM8976_S1_P2_MASK     0xfc000000
+#define MSM8976_S2_P2_MASK     0xfc0
+#define MSM8976_S3_P2_MASK     0xfc0000
+#define MSM8976_S4_P2_MASK     0xfc000
+#define MSM8976_S5_P2_MASK     0xfc000000
+#define MSM8976_S6_P2_MASK     0xfc0
+#define MSM8976_S7_P2_MASK     0xfc0000
+#define MSM8976_S8_P2_MASK     0x7e00
+#define MSM8976_S9_P2_MASK     0x7e00000
+#define MSM8976_S10_P2_MASK    0x7e
+
+#define MSM8976_S0_P1_SHIFT    8
+#define MSM8976_S1_P1_SHIFT    20
+#define MSM8976_S2_P1_SHIFT    0
+#define MSM8976_S3_P1_SHIFT    12
+#define MSM8976_S4_P1_SHIFT    8
+#define MSM8976_S5_P1_SHIFT    20
+#define MSM8976_S6_P1_SHIFT    0
+#define MSM8976_S7_P1_SHIFT    12
+#define MSM8976_S8_P1_SHIFT    3
+#define MSM8976_S9_P1_SHIFT    15
+#define MSM8976_S10_P1_SHIFT   27
+#define MSM8976_S10_P1_SHIFT_1 0
+
+#define MSM8976_S0_P2_SHIFT    14
+#define MSM8976_S1_P2_SHIFT    26
+#define MSM8976_S2_P2_SHIFT    6
+#define MSM8976_S3_P2_SHIFT    18
+#define MSM8976_S4_P2_SHIFT    14
+#define MSM8976_S5_P2_SHIFT    26
+#define MSM8976_S6_P2_SHIFT    6
+#define MSM8976_S7_P2_SHIFT    18
+#define MSM8976_S8_P2_SHIFT    9
+#define MSM8976_S9_P2_SHIFT    21
+#define MSM8976_S10_P2_SHIFT   1
+
+#define MSM8976_CAL_SEL_MASK   0x3
+
+#define MSM8976_CAL_DEGC_PT1   30
+#define MSM8976_CAL_DEGC_PT2   120
+#define MSM8976_SLOPE_FACTOR   1000
+#define MSM8976_SLOPE_DEFAULT  3200
 
 /* eeprom layout data for qcs404/405 (v1) */
 #define BASE0_MASK     0x000007f8
 #define CAL_SEL_MASK   7
 #define CAL_SEL_SHIFT  0
 
+static void compute_intercept_slope_8976(struct tsens_priv *priv,
+                             u32 *p1, u32 *p2, u32 mode)
+{
+       int i;
+
+       priv->sensor[0].slope = 3313;
+       priv->sensor[1].slope = 3275;
+       priv->sensor[2].slope = 3320;
+       priv->sensor[3].slope = 3246;
+       priv->sensor[4].slope = 3279;
+       priv->sensor[5].slope = 3257;
+       priv->sensor[6].slope = 3234;
+       priv->sensor[7].slope = 3269;
+       priv->sensor[8].slope = 3255;
+       priv->sensor[9].slope = 3239;
+       priv->sensor[10].slope = 3286;
+
+       for (i = 0; i < priv->num_sensors; i++) {
+               priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) -
+                               (MSM8976_CAL_DEGC_PT1 *
+                               priv->sensor[i].slope);
+       }
+}
+
 static int calibrate_v1(struct tsens_priv *priv)
 {
        u32 base0 = 0, base1 = 0;
@@ -143,7 +232,72 @@ static int calibrate_v1(struct tsens_priv *priv)
        return 0;
 }
 
-/* v1.x: qcs404,405 */
+static int calibrate_8976(struct tsens_priv *priv)
+{
+       int base0 = 0, base1 = 0, i;
+       u32 p1[11], p2[11];
+       int mode = 0, tmp = 0;
+       u32 *qfprom_cdata;
+
+       qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
+       if (IS_ERR(qfprom_cdata))
+               return PTR_ERR(qfprom_cdata);
+
+       mode = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK);
+       dev_dbg(priv->dev, "calibration mode is %d\n", mode);
+
+       switch (mode) {
+       case TWO_PT_CALIB:
+               base1 = (qfprom_cdata[2] & MSM8976_BASE1_MASK) >> MSM8976_BASE1_SHIFT;
+               p2[0] = (qfprom_cdata[0] & MSM8976_S0_P2_MASK) >> MSM8976_S0_P2_SHIFT;
+               p2[1] = (qfprom_cdata[0] & MSM8976_S1_P2_MASK) >> MSM8976_S1_P2_SHIFT;
+               p2[2] = (qfprom_cdata[1] & MSM8976_S2_P2_MASK) >> MSM8976_S2_P2_SHIFT;
+               p2[3] = (qfprom_cdata[1] & MSM8976_S3_P2_MASK) >> MSM8976_S3_P2_SHIFT;
+               p2[4] = (qfprom_cdata[2] & MSM8976_S4_P2_MASK) >> MSM8976_S4_P2_SHIFT;
+               p2[5] = (qfprom_cdata[2] & MSM8976_S5_P2_MASK) >> MSM8976_S5_P2_SHIFT;
+               p2[6] = (qfprom_cdata[3] & MSM8976_S6_P2_MASK) >> MSM8976_S6_P2_SHIFT;
+               p2[7] = (qfprom_cdata[3] & MSM8976_S7_P2_MASK) >> MSM8976_S7_P2_SHIFT;
+               p2[8] = (qfprom_cdata[4] & MSM8976_S8_P2_MASK) >> MSM8976_S8_P2_SHIFT;
+               p2[9] = (qfprom_cdata[4] & MSM8976_S9_P2_MASK) >> MSM8976_S9_P2_SHIFT;
+               p2[10] = (qfprom_cdata[5] & MSM8976_S10_P2_MASK) >> MSM8976_S10_P2_SHIFT;
+
+               for (i = 0; i < priv->num_sensors; i++)
+                       p2[i] = ((base1 + p2[i]) << 2);
+               /* Fall through */
+       case ONE_PT_CALIB2:
+               base0 = qfprom_cdata[0] & MSM8976_BASE0_MASK;
+               p1[0] = (qfprom_cdata[0] & MSM8976_S0_P1_MASK) >> MSM8976_S0_P1_SHIFT;
+               p1[1] = (qfprom_cdata[0] & MSM8976_S1_P1_MASK) >> MSM8976_S1_P1_SHIFT;
+               p1[2] = (qfprom_cdata[1] & MSM8976_S2_P1_MASK) >> MSM8976_S2_P1_SHIFT;
+               p1[3] = (qfprom_cdata[1] & MSM8976_S3_P1_MASK) >> MSM8976_S3_P1_SHIFT;
+               p1[4] = (qfprom_cdata[2] & MSM8976_S4_P1_MASK) >> MSM8976_S4_P1_SHIFT;
+               p1[5] = (qfprom_cdata[2] & MSM8976_S5_P1_MASK) >> MSM8976_S5_P1_SHIFT;
+               p1[6] = (qfprom_cdata[3] & MSM8976_S6_P1_MASK) >> MSM8976_S6_P1_SHIFT;
+               p1[7] = (qfprom_cdata[3] & MSM8976_S7_P1_MASK) >> MSM8976_S7_P1_SHIFT;
+               p1[8] = (qfprom_cdata[4] & MSM8976_S8_P1_MASK) >> MSM8976_S8_P1_SHIFT;
+               p1[9] = (qfprom_cdata[4] & MSM8976_S9_P1_MASK) >> MSM8976_S9_P1_SHIFT;
+               p1[10] = (qfprom_cdata[4] & MSM8976_S10_P1_MASK) >> MSM8976_S10_P1_SHIFT;
+               tmp = (qfprom_cdata[5] & MSM8976_S10_P1_MASK_1) << MSM8976_S10_P1_SHIFT_1;
+               p1[10] |= tmp;
+
+               for (i = 0; i < priv->num_sensors; i++)
+                       p1[i] = (((base0) + p1[i]) << 2);
+               break;
+       default:
+               for (i = 0; i < priv->num_sensors; i++) {
+                       p1[i] = 500;
+                       p2[i] = 780;
+               }
+               break;
+       }
+
+       compute_intercept_slope_8976(priv, p1, p2, mode);
+       kfree(qfprom_cdata);
+
+       return 0;
+}
+
+/* v1.x: msm8956,8976,qcs404,405 */
 
 static const struct tsens_features tsens_v1_feat = {
        .ver_major      = VER_1_X,
@@ -168,9 +322,36 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
        /* INTERRUPT ENABLE */
        [INT_EN]     = REG_FIELD(TM_INT_EN_OFF, 0, 0),
 
+       /* UPPER/LOWER TEMPERATURE THRESHOLDS */
+       REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH,    TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF,  0,  9),
+       REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH,     TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19),
+
+       /* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */
+       REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20),
+       REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR,  TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21),
+       [LOW_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  0,  0),
+       [LOW_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  1,  1),
+       [LOW_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  2,  2),
+       [LOW_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  3,  3),
+       [LOW_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  4,  4),
+       [LOW_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  5,  5),
+       [LOW_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  6,  6),
+       [LOW_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  7,  7),
+       [UP_INT_STATUS_0]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  8,  8),
+       [UP_INT_STATUS_1]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  9,  9),
+       [UP_INT_STATUS_2]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 10, 10),
+       [UP_INT_STATUS_3]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 11, 11),
+       [UP_INT_STATUS_4]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 12, 12),
+       [UP_INT_STATUS_5]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 13, 13),
+       [UP_INT_STATUS_6]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 14, 14),
+       [UP_INT_STATUS_7]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 15, 15),
+
+       /* NO CRITICAL INTERRUPT SUPPORT on v1 */
+
        /* Sn_STATUS */
        REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP,    TM_Sn_STATUS_OFF,  0,  9),
        REG_FIELD_FOR_EACH_SENSOR11(VALID,        TM_Sn_STATUS_OFF, 14, 14),
+       /* xxx_STATUS bits: 1 == threshold violated */
        REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS,   TM_Sn_STATUS_OFF, 10, 10),
        REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
        REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
@@ -192,3 +373,18 @@ const struct tsens_plat_data data_tsens_v1 = {
        .feat           = &tsens_v1_feat,
        .fields = tsens_v1_regfields,
 };
+
+static const struct tsens_ops ops_8976 = {
+       .init           = init_common,
+       .calibrate      = calibrate_8976,
+       .get_temp       = get_temp_tsens_valid,
+};
+
+/* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */
+const struct tsens_plat_data data_8976 = {
+       .num_sensors    = 11,
+       .ops            = &ops_8976,
+       .hw_ids         = (unsigned int[]){0, 1, 2, 4, 5, 6, 7, 8, 9, 10},
+       .feat           = &tsens_v1_feat,
+       .fields         = tsens_v1_regfields,
+};
index 0a4f2b8..a4d15e1 100644 (file)
@@ -50,9 +50,22 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
        /* v2 has separate enables for UPPER/LOWER/CRITICAL interrupts */
        [INT_EN]  = REG_FIELD(TM_INT_EN_OFF, 0, 2),
 
+       /* TEMPERATURE THRESHOLDS */
+       REG_FIELD_FOR_EACH_SENSOR16(LOW_THRESH, TM_Sn_UPPER_LOWER_THRESHOLD_OFF,  0,  11),
+       REG_FIELD_FOR_EACH_SENSOR16(UP_THRESH,  TM_Sn_UPPER_LOWER_THRESHOLD_OFF, 12,  23),
+
+       /* INTERRUPTS [CLEAR/STATUS/MASK] */
+       REG_FIELD_SPLIT_BITS_0_15(LOW_INT_STATUS,  TM_UPPER_LOWER_INT_STATUS_OFF),
+       REG_FIELD_SPLIT_BITS_0_15(LOW_INT_CLEAR,   TM_UPPER_LOWER_INT_CLEAR_OFF),
+       REG_FIELD_SPLIT_BITS_0_15(LOW_INT_MASK,    TM_UPPER_LOWER_INT_MASK_OFF),
+       REG_FIELD_SPLIT_BITS_16_31(UP_INT_STATUS,  TM_UPPER_LOWER_INT_STATUS_OFF),
+       REG_FIELD_SPLIT_BITS_16_31(UP_INT_CLEAR,   TM_UPPER_LOWER_INT_CLEAR_OFF),
+       REG_FIELD_SPLIT_BITS_16_31(UP_INT_MASK,    TM_UPPER_LOWER_INT_MASK_OFF),
+
        /* Sn_STATUS */
        REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP,       TM_Sn_STATUS_OFF,  0,  11),
        REG_FIELD_FOR_EACH_SENSOR16(VALID,           TM_Sn_STATUS_OFF, 21,  21),
+       /* xxx_STATUS bits: 1 == threshold violated */
        REG_FIELD_FOR_EACH_SENSOR16(MIN_STATUS,      TM_Sn_STATUS_OFF, 16,  16),
        REG_FIELD_FOR_EACH_SENSOR16(LOWER_STATUS,    TM_Sn_STATUS_OFF, 17,  17),
        REG_FIELD_FOR_EACH_SENSOR16(UPPER_STATUS,    TM_Sn_STATUS_OFF, 18,  18),
index 0627d86..015e7d2 100644 (file)
@@ -3,9 +3,11 @@
  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/debugfs.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
 
 static int tsens_get_temp(void *data, int *temp)
 {
-       const struct tsens_sensor *s = data;
+       struct tsens_sensor *s = data;
        struct tsens_priv *priv = s->priv;
 
-       return priv->ops->get_temp(priv, s->id, temp);
+       return priv->ops->get_temp(s, temp);
 }
 
 static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
 {
-       const struct tsens_sensor *s = data;
+       struct tsens_sensor *s = data;
        struct tsens_priv *priv = s->priv;
 
        if (priv->ops->get_trend)
-               return priv->ops->get_trend(priv, s->id, trend);
+               return priv->ops->get_trend(s, trend);
 
        return -ENOTSUPP;
 }
@@ -61,6 +63,9 @@ static const struct of_device_id tsens_table[] = {
                .compatible = "qcom,msm8974-tsens",
                .data = &data_8974,
        }, {
+               .compatible = "qcom,msm8976-tsens",
+               .data = &data_8976,
+       }, {
                .compatible = "qcom,msm8996-tsens",
                .data = &data_8996,
        }, {
@@ -77,17 +82,18 @@ MODULE_DEVICE_TABLE(of, tsens_table);
 static const struct thermal_zone_of_device_ops tsens_of_ops = {
        .get_temp = tsens_get_temp,
        .get_trend = tsens_get_trend,
+       .set_trips = tsens_set_trips,
 };
 
 static int tsens_register(struct tsens_priv *priv)
 {
-       int i;
+       int i, ret, irq;
        struct thermal_zone_device *tzd;
+       struct platform_device *pdev;
 
        for (i = 0;  i < priv->num_sensors; i++) {
                priv->sensor[i].priv = priv;
-               priv->sensor[i].id = i;
-               tzd = devm_thermal_zone_of_sensor_register(priv->dev, i,
+               tzd = devm_thermal_zone_of_sensor_register(priv->dev, priv->sensor[i].hw_id,
                                                           &priv->sensor[i],
                                                           &tsens_of_ops);
                if (IS_ERR(tzd))
@@ -96,7 +102,31 @@ static int tsens_register(struct tsens_priv *priv)
                if (priv->ops->enable)
                        priv->ops->enable(priv, i);
        }
-       return 0;
+
+       pdev = of_find_device_by_node(priv->dev->of_node);
+       if (!pdev)
+               return -ENODEV;
+
+       irq = platform_get_irq_byname(pdev, "uplow");
+       if (irq < 0) {
+               ret = irq;
+               goto err_put_device;
+       }
+
+       ret = devm_request_threaded_irq(&pdev->dev, irq,
+                                       NULL, tsens_irq_thread,
+                                       IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+                                       dev_name(&pdev->dev), priv);
+       if (ret) {
+               dev_err(&pdev->dev, "%s: failed to get irq\n", __func__);
+               goto err_put_device;
+       }
+
+       enable_irq_wake(irq);
+
+err_put_device:
+       put_device(&pdev->dev);
+       return ret;
 }
 
 static int tsens_probe(struct platform_device *pdev)
@@ -128,7 +158,7 @@ static int tsens_probe(struct platform_device *pdev)
                of_property_read_u32(np, "#qcom,sensors", &num_sensors);
 
        if (num_sensors <= 0) {
-               dev_err(dev, "invalid number of sensors\n");
+               dev_err(dev, "%s: invalid number of sensors\n", __func__);
                return -EINVAL;
        }
 
@@ -150,12 +180,14 @@ static int tsens_probe(struct platform_device *pdev)
        priv->feat = data->feat;
        priv->fields = data->fields;
 
+       platform_set_drvdata(pdev, priv);
+
        if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
                return -EINVAL;
 
        ret = priv->ops->init(priv);
        if (ret < 0) {
-               dev_err(dev, "tsens init failed\n");
+               dev_err(dev, "%s: init failed\n", __func__);
                return ret;
        }
 
@@ -163,22 +195,20 @@ static int tsens_probe(struct platform_device *pdev)
                ret = priv->ops->calibrate(priv);
                if (ret < 0) {
                        if (ret != -EPROBE_DEFER)
-                               dev_err(dev, "tsens calibration failed\n");
+                               dev_err(dev, "%s: calibration failed\n", __func__);
                        return ret;
                }
        }
 
-       ret = tsens_register(priv);
-
-       platform_set_drvdata(pdev, priv);
-
-       return ret;
+       return tsens_register(priv);
 }
 
 static int tsens_remove(struct platform_device *pdev)
 {
        struct tsens_priv *priv = platform_get_drvdata(pdev);
 
+       debugfs_remove_recursive(priv->debug_root);
+       tsens_disable_irq(priv);
        if (priv->ops->disable)
                priv->ops->disable(priv);
 
index b89083b..e24a865 100644 (file)
 #define CAL_DEGC_PT2           120
 #define SLOPE_FACTOR           1000
 #define SLOPE_DEFAULT          3200
+#define THRESHOLD_MAX_ADC_CODE 0x3ff
+#define THRESHOLD_MIN_ADC_CODE 0x0
 
-
+#include <linux/interrupt.h>
 #include <linux/thermal.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
@@ -27,12 +29,16 @@ enum tsens_ver {
        VER_2_X,
 };
 
+enum tsens_irq_type {
+       LOWER,
+       UPPER,
+};
+
 /**
  * struct tsens_sensor - data for each sensor connected to the tsens device
  * @priv: tsens device instance that this sensor is connected to
  * @tzd: pointer to the thermal zone that this sensor is in
  * @offset: offset of temperature adjustment curve
- * @id: Sensor ID
  * @hw_id: HW ID can be used in case of platform-specific IDs
  * @slope: slope of temperature adjustment curve
  * @status: 8960-specific variable to track 8960 and 8660 status register offset
@@ -41,7 +47,6 @@ struct tsens_sensor {
        struct tsens_priv               *priv;
        struct thermal_zone_device      *tzd;
        int                             offset;
-       unsigned int                    id;
        unsigned int                    hw_id;
        int                             slope;
        u32                             status;
@@ -62,13 +67,13 @@ struct tsens_ops {
        /* mandatory callbacks */
        int (*init)(struct tsens_priv *priv);
        int (*calibrate)(struct tsens_priv *priv);
-       int (*get_temp)(struct tsens_priv *priv, int i, int *temp);
+       int (*get_temp)(struct tsens_sensor *s, int *temp);
        /* optional callbacks */
        int (*enable)(struct tsens_priv *priv, int i);
        void (*disable)(struct tsens_priv *priv);
        int (*suspend)(struct tsens_priv *priv);
        int (*resume)(struct tsens_priv *priv);
-       int (*get_trend)(struct tsens_priv *priv, int i, enum thermal_trend *trend);
+       int (*get_trend)(struct tsens_sensor *s, enum thermal_trend *trend);
 };
 
 #define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
@@ -102,22 +107,66 @@ struct tsens_ops {
        [_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \
        [_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit)
 
-/* reg_field IDs to use as an index into an array */
+#define REG_FIELD_SPLIT_BITS_0_15(_name, _offset)              \
+       [_name##_##0]  = REG_FIELD(_offset,  0,  0),            \
+       [_name##_##1]  = REG_FIELD(_offset,  1,  1),    \
+       [_name##_##2]  = REG_FIELD(_offset,  2,  2),    \
+       [_name##_##3]  = REG_FIELD(_offset,  3,  3),    \
+       [_name##_##4]  = REG_FIELD(_offset,  4,  4),    \
+       [_name##_##5]  = REG_FIELD(_offset,  5,  5),    \
+       [_name##_##6]  = REG_FIELD(_offset,  6,  6),    \
+       [_name##_##7]  = REG_FIELD(_offset,  7,  7),    \
+       [_name##_##8]  = REG_FIELD(_offset,  8,  8),    \
+       [_name##_##9]  = REG_FIELD(_offset,  9,  9),    \
+       [_name##_##10] = REG_FIELD(_offset, 10, 10),    \
+       [_name##_##11] = REG_FIELD(_offset, 11, 11),    \
+       [_name##_##12] = REG_FIELD(_offset, 12, 12),    \
+       [_name##_##13] = REG_FIELD(_offset, 13, 13),    \
+       [_name##_##14] = REG_FIELD(_offset, 14, 14),    \
+       [_name##_##15] = REG_FIELD(_offset, 15, 15)
+
+#define REG_FIELD_SPLIT_BITS_16_31(_name, _offset)             \
+       [_name##_##0]  = REG_FIELD(_offset, 16, 16),            \
+       [_name##_##1]  = REG_FIELD(_offset, 17, 17),    \
+       [_name##_##2]  = REG_FIELD(_offset, 18, 18),    \
+       [_name##_##3]  = REG_FIELD(_offset, 19, 19),    \
+       [_name##_##4]  = REG_FIELD(_offset, 20, 20),    \
+       [_name##_##5]  = REG_FIELD(_offset, 21, 21),    \
+       [_name##_##6]  = REG_FIELD(_offset, 22, 22),    \
+       [_name##_##7]  = REG_FIELD(_offset, 23, 23),    \
+       [_name##_##8]  = REG_FIELD(_offset, 24, 24),    \
+       [_name##_##9]  = REG_FIELD(_offset, 25, 25),    \
+       [_name##_##10] = REG_FIELD(_offset, 26, 26),    \
+       [_name##_##11] = REG_FIELD(_offset, 27, 27),    \
+       [_name##_##12] = REG_FIELD(_offset, 28, 28),    \
+       [_name##_##13] = REG_FIELD(_offset, 29, 29),    \
+       [_name##_##14] = REG_FIELD(_offset, 30, 30),    \
+       [_name##_##15] = REG_FIELD(_offset, 31, 31)
+
+/*
+ * reg_field IDs to use as an index into an array
+ * If you change the order of the entries, check the devm_regmap_field_alloc()
+ * calls in init_common()
+ */
 enum regfield_ids {
        /* ----- SROT ------ */
        /* HW_VER */
-       VER_MAJOR = 0,
+       VER_MAJOR,
        VER_MINOR,
        VER_STEP,
        /* CTRL_OFFSET */
-       TSENS_EN =  3,
+       TSENS_EN,
        TSENS_SW_RST,
        SENSOR_EN,
        CODE_OR_TEMP,
 
        /* ----- TM ------ */
+       /* TRDY */
+       TRDY,
+       /* INTERRUPT ENABLE */
+       INT_EN, /* v2+ has separate enables for crit, upper and lower irq */
        /* STATUS */
-       LAST_TEMP_0 = 7,        /* Last temperature reading */
+       LAST_TEMP_0,    /* Last temperature reading */
        LAST_TEMP_1,
        LAST_TEMP_2,
        LAST_TEMP_3,
@@ -133,7 +182,7 @@ enum regfield_ids {
        LAST_TEMP_13,
        LAST_TEMP_14,
        LAST_TEMP_15,
-       VALID_0 = 23,           /* VALID reading or not */
+       VALID_0,                /* VALID reading or not */
        VALID_1,
        VALID_2,
        VALID_3,
@@ -149,38 +198,6 @@ enum regfield_ids {
        VALID_13,
        VALID_14,
        VALID_15,
-       MIN_STATUS_0,           /* MIN threshold violated */
-       MIN_STATUS_1,
-       MIN_STATUS_2,
-       MIN_STATUS_3,
-       MIN_STATUS_4,
-       MIN_STATUS_5,
-       MIN_STATUS_6,
-       MIN_STATUS_7,
-       MIN_STATUS_8,
-       MIN_STATUS_9,
-       MIN_STATUS_10,
-       MIN_STATUS_11,
-       MIN_STATUS_12,
-       MIN_STATUS_13,
-       MIN_STATUS_14,
-       MIN_STATUS_15,
-       MAX_STATUS_0,           /* MAX threshold violated */
-       MAX_STATUS_1,
-       MAX_STATUS_2,
-       MAX_STATUS_3,
-       MAX_STATUS_4,
-       MAX_STATUS_5,
-       MAX_STATUS_6,
-       MAX_STATUS_7,
-       MAX_STATUS_8,
-       MAX_STATUS_9,
-       MAX_STATUS_10,
-       MAX_STATUS_11,
-       MAX_STATUS_12,
-       MAX_STATUS_13,
-       MAX_STATUS_14,
-       MAX_STATUS_15,
        LOWER_STATUS_0, /* LOWER threshold violated */
        LOWER_STATUS_1,
        LOWER_STATUS_2,
@@ -197,6 +214,70 @@ enum regfield_ids {
        LOWER_STATUS_13,
        LOWER_STATUS_14,
        LOWER_STATUS_15,
+       LOW_INT_STATUS_0,       /* LOWER interrupt status */
+       LOW_INT_STATUS_1,
+       LOW_INT_STATUS_2,
+       LOW_INT_STATUS_3,
+       LOW_INT_STATUS_4,
+       LOW_INT_STATUS_5,
+       LOW_INT_STATUS_6,
+       LOW_INT_STATUS_7,
+       LOW_INT_STATUS_8,
+       LOW_INT_STATUS_9,
+       LOW_INT_STATUS_10,
+       LOW_INT_STATUS_11,
+       LOW_INT_STATUS_12,
+       LOW_INT_STATUS_13,
+       LOW_INT_STATUS_14,
+       LOW_INT_STATUS_15,
+       LOW_INT_CLEAR_0,        /* LOWER interrupt clear */
+       LOW_INT_CLEAR_1,
+       LOW_INT_CLEAR_2,
+       LOW_INT_CLEAR_3,
+       LOW_INT_CLEAR_4,
+       LOW_INT_CLEAR_5,
+       LOW_INT_CLEAR_6,
+       LOW_INT_CLEAR_7,
+       LOW_INT_CLEAR_8,
+       LOW_INT_CLEAR_9,
+       LOW_INT_CLEAR_10,
+       LOW_INT_CLEAR_11,
+       LOW_INT_CLEAR_12,
+       LOW_INT_CLEAR_13,
+       LOW_INT_CLEAR_14,
+       LOW_INT_CLEAR_15,
+       LOW_INT_MASK_0, /* LOWER interrupt mask */
+       LOW_INT_MASK_1,
+       LOW_INT_MASK_2,
+       LOW_INT_MASK_3,
+       LOW_INT_MASK_4,
+       LOW_INT_MASK_5,
+       LOW_INT_MASK_6,
+       LOW_INT_MASK_7,
+       LOW_INT_MASK_8,
+       LOW_INT_MASK_9,
+       LOW_INT_MASK_10,
+       LOW_INT_MASK_11,
+       LOW_INT_MASK_12,
+       LOW_INT_MASK_13,
+       LOW_INT_MASK_14,
+       LOW_INT_MASK_15,
+       LOW_THRESH_0,           /* LOWER threshold values */
+       LOW_THRESH_1,
+       LOW_THRESH_2,
+       LOW_THRESH_3,
+       LOW_THRESH_4,
+       LOW_THRESH_5,
+       LOW_THRESH_6,
+       LOW_THRESH_7,
+       LOW_THRESH_8,
+       LOW_THRESH_9,
+       LOW_THRESH_10,
+       LOW_THRESH_11,
+       LOW_THRESH_12,
+       LOW_THRESH_13,
+       LOW_THRESH_14,
+       LOW_THRESH_15,
        UPPER_STATUS_0, /* UPPER threshold violated */
        UPPER_STATUS_1,
        UPPER_STATUS_2,
@@ -213,6 +294,70 @@ enum regfield_ids {
        UPPER_STATUS_13,
        UPPER_STATUS_14,
        UPPER_STATUS_15,
+       UP_INT_STATUS_0,        /* UPPER interrupt status */
+       UP_INT_STATUS_1,
+       UP_INT_STATUS_2,
+       UP_INT_STATUS_3,
+       UP_INT_STATUS_4,
+       UP_INT_STATUS_5,
+       UP_INT_STATUS_6,
+       UP_INT_STATUS_7,
+       UP_INT_STATUS_8,
+       UP_INT_STATUS_9,
+       UP_INT_STATUS_10,
+       UP_INT_STATUS_11,
+       UP_INT_STATUS_12,
+       UP_INT_STATUS_13,
+       UP_INT_STATUS_14,
+       UP_INT_STATUS_15,
+       UP_INT_CLEAR_0, /* UPPER interrupt clear */
+       UP_INT_CLEAR_1,
+       UP_INT_CLEAR_2,
+       UP_INT_CLEAR_3,
+       UP_INT_CLEAR_4,
+       UP_INT_CLEAR_5,
+       UP_INT_CLEAR_6,
+       UP_INT_CLEAR_7,
+       UP_INT_CLEAR_8,
+       UP_INT_CLEAR_9,
+       UP_INT_CLEAR_10,
+       UP_INT_CLEAR_11,
+       UP_INT_CLEAR_12,
+       UP_INT_CLEAR_13,
+       UP_INT_CLEAR_14,
+       UP_INT_CLEAR_15,
+       UP_INT_MASK_0,          /* UPPER interrupt mask */
+       UP_INT_MASK_1,
+       UP_INT_MASK_2,
+       UP_INT_MASK_3,
+       UP_INT_MASK_4,
+       UP_INT_MASK_5,
+       UP_INT_MASK_6,
+       UP_INT_MASK_7,
+       UP_INT_MASK_8,
+       UP_INT_MASK_9,
+       UP_INT_MASK_10,
+       UP_INT_MASK_11,
+       UP_INT_MASK_12,
+       UP_INT_MASK_13,
+       UP_INT_MASK_14,
+       UP_INT_MASK_15,
+       UP_THRESH_0,            /* UPPER threshold values */
+       UP_THRESH_1,
+       UP_THRESH_2,
+       UP_THRESH_3,
+       UP_THRESH_4,
+       UP_THRESH_5,
+       UP_THRESH_6,
+       UP_THRESH_7,
+       UP_THRESH_8,
+       UP_THRESH_9,
+       UP_THRESH_10,
+       UP_THRESH_11,
+       UP_THRESH_12,
+       UP_THRESH_13,
+       UP_THRESH_14,
+       UP_THRESH_15,
        CRITICAL_STATUS_0,      /* CRITICAL threshold violated */
        CRITICAL_STATUS_1,
        CRITICAL_STATUS_2,
@@ -229,13 +374,38 @@ enum regfield_ids {
        CRITICAL_STATUS_13,
        CRITICAL_STATUS_14,
        CRITICAL_STATUS_15,
-       /* TRDY */
-       TRDY,
-       /* INTERRUPT ENABLE */
-       INT_EN, /* Pre-V1, V1.x */
-       LOW_INT_EN,     /* V2.x */
-       UP_INT_EN,      /* V2.x */
-       CRIT_INT_EN,    /* V2.x */
+       MIN_STATUS_0,           /* MIN threshold violated */
+       MIN_STATUS_1,
+       MIN_STATUS_2,
+       MIN_STATUS_3,
+       MIN_STATUS_4,
+       MIN_STATUS_5,
+       MIN_STATUS_6,
+       MIN_STATUS_7,
+       MIN_STATUS_8,
+       MIN_STATUS_9,
+       MIN_STATUS_10,
+       MIN_STATUS_11,
+       MIN_STATUS_12,
+       MIN_STATUS_13,
+       MIN_STATUS_14,
+       MIN_STATUS_15,
+       MAX_STATUS_0,           /* MAX threshold violated */
+       MAX_STATUS_1,
+       MAX_STATUS_2,
+       MAX_STATUS_3,
+       MAX_STATUS_4,
+       MAX_STATUS_5,
+       MAX_STATUS_6,
+       MAX_STATUS_7,
+       MAX_STATUS_8,
+       MAX_STATUS_9,
+       MAX_STATUS_10,
+       MAX_STATUS_11,
+       MAX_STATUS_12,
+       MAX_STATUS_13,
+       MAX_STATUS_14,
+       MAX_STATUS_15,
 
        /* Keep last */
        MAX_REGFIELDS
@@ -295,6 +465,8 @@ struct tsens_context {
  * @feat: features of the IP
  * @fields: bitfield locations
  * @ops: pointer to list of callbacks supported by this device
+ * @debug_root: pointer to debugfs dentry for all tsens
+ * @debug: pointer to debugfs dentry for tsens controller
  * @sensor: list of sensors attached to this device
  */
 struct tsens_priv {
@@ -303,19 +475,31 @@ struct tsens_priv {
        struct regmap                   *tm_map;
        struct regmap                   *srot_map;
        u32                             tm_offset;
+
+       /* lock for upper/lower threshold interrupts */
+       spinlock_t                      ul_lock;
+
        struct regmap_field             *rf[MAX_REGFIELDS];
        struct tsens_context            ctx;
        const struct tsens_features     *feat;
        const struct reg_field          *fields;
        const struct tsens_ops          *ops;
+
+       struct dentry                   *debug_root;
+       struct dentry                   *debug;
+
        struct tsens_sensor             sensor[0];
 };
 
 char *qfprom_read(struct device *dev, const char *cname);
 void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
 int init_common(struct tsens_priv *priv);
-int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp);
-int get_temp_common(struct tsens_priv *priv, int i, int *temp);
+int get_temp_tsens_valid(struct tsens_sensor *s, int *temp);
+int get_temp_common(struct tsens_sensor *s, int *temp);
+int tsens_enable_irq(struct tsens_priv *priv);
+void tsens_disable_irq(struct tsens_priv *priv);
+int tsens_set_trips(void *_sensor, int low, int high);
+irqreturn_t tsens_irq_thread(int irq, void *data);
 
 /* TSENS target */
 extern const struct tsens_plat_data data_8960;
@@ -324,7 +508,7 @@ extern const struct tsens_plat_data data_8960;
 extern const struct tsens_plat_data data_8916, data_8974;
 
 /* TSENS v1 targets */
-extern const struct tsens_plat_data data_tsens_v1;
+extern const struct tsens_plat_data data_tsens_v1, data_8976;
 
 /* TSENS v2 targets */
 extern const struct tsens_plat_data data_8996, data_tsens_v2;
index 39542c6..45e9fcb 100644 (file)
 
 #include "thermal_core.h"
 
-#define SITES_MAX      16
+#define SITES_MAX              16
+#define TMR_DISABLE            0x0
+#define TMR_ME                 0x80000000
+#define TMR_ALPF               0x0c000000
+#define TMR_ALPF_V2            0x03000000
+#define TMTMIR_DEFAULT 0x0000000f
+#define TIER_DISABLE   0x0
+#define TEUMR0_V2              0x51009c00
+#define TMU_VER1               0x1
+#define TMU_VER2               0x2
 
 /*
  * QorIQ TMU Registers
@@ -24,17 +33,12 @@ struct qoriq_tmu_site_regs {
        u8 res0[0x8];
 };
 
-struct qoriq_tmu_regs {
+struct qoriq_tmu_regs_v1 {
        u32 tmr;                /* Mode Register */
-#define TMR_DISABLE    0x0
-#define TMR_ME         0x80000000
-#define TMR_ALPF       0x0c000000
        u32 tsr;                /* Status Register */
        u32 tmtmir;             /* Temperature measurement interval Register */
-#define TMTMIR_DEFAULT 0x0000000f
        u8 res0[0x14];
        u32 tier;               /* Interrupt Enable Register */
-#define TIER_DISABLE   0x0
        u32 tidr;               /* Interrupt Detect Register */
        u32 tiscr;              /* Interrupt Site Capture Register */
        u32 ticscr;             /* Interrupt Critical Site Capture Register */
@@ -54,10 +58,50 @@ struct qoriq_tmu_regs {
        u32 ipbrr0;             /* IP Block Revision Register 0 */
        u32 ipbrr1;             /* IP Block Revision Register 1 */
        u8 res6[0x310];
-       u32 ttr0cr;             /* Temperature Range 0 Control Register */
-       u32 ttr1cr;             /* Temperature Range 1 Control Register */
-       u32 ttr2cr;             /* Temperature Range 2 Control Register */
-       u32 ttr3cr;             /* Temperature Range 3 Control Register */
+       u32 ttrcr[4];           /* Temperature Range Control Register */
+};
+
+struct qoriq_tmu_regs_v2 {
+       u32 tmr;                /* Mode Register */
+       u32 tsr;                /* Status Register */
+       u32 tmsr;               /* monitor site register */
+       u32 tmtmir;             /* Temperature measurement interval Register */
+       u8 res0[0x10];
+       u32 tier;               /* Interrupt Enable Register */
+       u32 tidr;               /* Interrupt Detect Register */
+       u8 res1[0x8];
+       u32 tiiscr;             /* interrupt immediate site capture register */
+       u32 tiascr;             /* interrupt average site capture register */
+       u32 ticscr;             /* Interrupt Critical Site Capture Register */
+       u32 res2;
+       u32 tmhtcr;             /* monitor high temperature capture register */
+       u32 tmltcr;             /* monitor low temperature capture register */
+       u32 tmrtrcr;    /* monitor rising temperature rate capture register */
+       u32 tmftrcr;    /* monitor falling temperature rate capture register */
+       u32 tmhtitr;    /* High Temperature Immediate Threshold */
+       u32 tmhtatr;    /* High Temperature Average Threshold */
+       u32 tmhtactr;   /* High Temperature Average Crit Threshold */
+       u32 res3;
+       u32 tmltitr;    /* monitor low temperature immediate threshold */
+       u32 tmltatr;    /* monitor low temperature average threshold register */
+       u32 tmltactr;   /* monitor low temperature average critical threshold */
+       u32 res4;
+       u32 tmrtrctr;   /* monitor rising temperature rate critical threshold */
+       u32 tmftrctr;   /* monitor falling temperature rate critical threshold*/
+       u8 res5[0x8];
+       u32 ttcfgr;     /* Temperature Configuration Register */
+       u32 tscfgr;     /* Sensor Configuration Register */
+       u8 res6[0x78];
+       struct qoriq_tmu_site_regs site[SITES_MAX];
+       u8 res7[0x9f8];
+       u32 ipbrr0;             /* IP Block Revision Register 0 */
+       u32 ipbrr1;             /* IP Block Revision Register 1 */
+       u8 res8[0x300];
+       u32 teumr0;
+       u32 teumr1;
+       u32 teumr2;
+       u32 res9;
+       u32 ttrcr[4];   /* Temperature Range Control Register */
 };
 
 struct qoriq_tmu_data;
@@ -72,7 +116,9 @@ struct qoriq_sensor {
 };
 
 struct qoriq_tmu_data {
-       struct qoriq_tmu_regs __iomem *regs;
+       int ver;
+       struct qoriq_tmu_regs_v1 __iomem *regs;
+       struct qoriq_tmu_regs_v2 __iomem *regs_v2;
        struct clk *clk;
        bool little_endian;
        struct qoriq_sensor     *sensor[SITES_MAX];
@@ -132,12 +178,23 @@ static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
                                return PTR_ERR(qdata->sensor[id]->tzd);
                }
 
-               sites |= 0x1 << (15 - id);
+               if (qdata->ver == TMU_VER1)
+                       sites |= 0x1 << (15 - id);
+               else
+                       sites |= 0x1 << id;
        }
 
        /* Enable monitoring */
-       if (sites != 0)
-               tmu_write(qdata, sites | TMR_ME | TMR_ALPF, &qdata->regs->tmr);
+       if (sites != 0) {
+               if (qdata->ver == TMU_VER1) {
+                       tmu_write(qdata, sites | TMR_ME | TMR_ALPF,
+                                       &qdata->regs->tmr);
+               } else {
+                       tmu_write(qdata, sites, &qdata->regs_v2->tmsr);
+                       tmu_write(qdata, TMR_ME | TMR_ALPF_V2,
+                                       &qdata->regs_v2->tmr);
+               }
+       }
 
        return 0;
 }
@@ -150,16 +207,21 @@ static int qoriq_tmu_calibration(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
 
-       if (of_property_read_u32_array(np, "fsl,tmu-range", range, 4)) {
-               dev_err(&pdev->dev, "missing calibration range.\n");
-               return -ENODEV;
+       len = of_property_count_u32_elems(np, "fsl,tmu-range");
+       if (len < 0 || len > 4) {
+               dev_err(&pdev->dev, "invalid range data.\n");
+               return len;
+       }
+
+       val = of_property_read_u32_array(np, "fsl,tmu-range", range, len);
+       if (val != 0) {
+               dev_err(&pdev->dev, "failed to read range data.\n");
+               return val;
        }
 
        /* Init temperature range registers */
-       tmu_write(data, range[0], &data->regs->ttr0cr);
-       tmu_write(data, range[1], &data->regs->ttr1cr);
-       tmu_write(data, range[2], &data->regs->ttr2cr);
-       tmu_write(data, range[3], &data->regs->ttr3cr);
+       for (i = 0; i < len; i++)
+               tmu_write(data, range[i], &data->regs->ttrcr[i]);
 
        calibration = of_get_property(np, "fsl,tmu-calibration", &len);
        if (calibration == NULL || len % 8) {
@@ -183,7 +245,12 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
        tmu_write(data, TIER_DISABLE, &data->regs->tier);
 
        /* Set update_interval */
-       tmu_write(data, TMTMIR_DEFAULT, &data->regs->tmtmir);
+       if (data->ver == TMU_VER1) {
+               tmu_write(data, TMTMIR_DEFAULT, &data->regs->tmtmir);
+       } else {
+               tmu_write(data, TMTMIR_DEFAULT, &data->regs_v2->tmtmir);
+               tmu_write(data, TEUMR0_V2, &data->regs_v2->teumr0);
+       }
 
        /* Disable monitoring */
        tmu_write(data, TMR_DISABLE, &data->regs->tmr);
@@ -192,6 +259,7 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
 static int qoriq_tmu_probe(struct platform_device *pdev)
 {
        int ret;
+       u32 ver;
        struct qoriq_tmu_data *data;
        struct device_node *np = pdev->dev.of_node;
 
@@ -220,6 +288,12 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
                return ret;
        }
 
+       /* version register offset at: 0xbf8 on both v1 and v2 */
+       ver = tmu_read(data, &data->regs->ipbrr0);
+       data->ver = (ver >> 8) & 0xff;
+       if (data->ver == TMU_VER2)
+               data->regs_v2 = (void __iomem *)data->regs;
+
        qoriq_tmu_init_device(data);    /* TMU initialization */
 
        ret = qoriq_tmu_calibration(pdev);      /* TMU calibration */
index 755d2b5..1460cf9 100644 (file)
@@ -315,6 +315,10 @@ static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
                .data = &rcar_gen3_ths_tj_1_m3_w,
        },
        {
+               .compatible = "renesas,r8a774b1-thermal",
+               .data = &rcar_gen3_ths_tj_1,
+       },
+       {
                .compatible = "renesas,r8a7795-thermal",
                .data = &rcar_gen3_ths_tj_1,
        },
index dcecf2e..ae5743c 100644 (file)
@@ -134,7 +134,8 @@ static int gadc_thermal_probe(struct platform_device *pdev)
        gti->channel = devm_iio_channel_get(&pdev->dev, "sensor-channel");
        if (IS_ERR(gti->channel)) {
                ret = PTR_ERR(gti->channel);
-               dev_err(&pdev->dev, "IIO channel not found: %d\n", ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "IIO channel not found: %d\n", ret);
                return ret;
        }
 
@@ -142,8 +143,10 @@ static int gadc_thermal_probe(struct platform_device *pdev)
                                                           &gadc_thermal_ops);
        if (IS_ERR(gti->tz_dev)) {
                ret = PTR_ERR(gti->tz_dev);
-               dev_err(&pdev->dev, "Thermal zone sensor register failed: %d\n",
-                       ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "Thermal zone sensor register failed: %d\n",
+                               ret);
                return ret;
        }
 
index d4481cc..9a321dc 100644 (file)
@@ -19,8 +19,6 @@
 #include <linux/reboot.h>
 #include <linux/string.h>
 #include <linux/of.h>
-#include <net/netlink.h>
-#include <net/genetlink.h>
 #include <linux/suspend.h>
 
 #define CREATE_TRACE_POINTS
@@ -304,7 +302,7 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
                                 &tz->poll_queue,
                                 msecs_to_jiffies(delay));
        else
-               cancel_delayed_work_sync(&tz->poll_queue);
+               cancel_delayed_work(&tz->poll_queue);
 }
 
 static void monitor_thermal_zone(struct thermal_zone_device *tz)
@@ -1414,7 +1412,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 
        mutex_unlock(&thermal_list_lock);
 
-       thermal_zone_device_set_polling(tz, 0);
+       cancel_delayed_work_sync(&tz->poll_queue);
 
        thermal_set_governor(tz, NULL);
 
@@ -1464,97 +1462,6 @@ exit:
 }
 EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
 
-#ifdef CONFIG_NET
-static const struct genl_multicast_group thermal_event_mcgrps[] = {
-       { .name = THERMAL_GENL_MCAST_GROUP_NAME, },
-};
-
-static struct genl_family thermal_event_genl_family __ro_after_init = {
-       .module = THIS_MODULE,
-       .name = THERMAL_GENL_FAMILY_NAME,
-       .version = THERMAL_GENL_VERSION,
-       .maxattr = THERMAL_GENL_ATTR_MAX,
-       .mcgrps = thermal_event_mcgrps,
-       .n_mcgrps = ARRAY_SIZE(thermal_event_mcgrps),
-};
-
-int thermal_generate_netlink_event(struct thermal_zone_device *tz,
-                                  enum events event)
-{
-       struct sk_buff *skb;
-       struct nlattr *attr;
-       struct thermal_genl_event *thermal_event;
-       void *msg_header;
-       int size;
-       int result;
-       static unsigned int thermal_event_seqnum;
-
-       if (!tz)
-               return -EINVAL;
-
-       /* allocate memory */
-       size = nla_total_size(sizeof(struct thermal_genl_event)) +
-              nla_total_size(0);
-
-       skb = genlmsg_new(size, GFP_ATOMIC);
-       if (!skb)
-               return -ENOMEM;
-
-       /* add the genetlink message header */
-       msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++,
-                                &thermal_event_genl_family, 0,
-                                THERMAL_GENL_CMD_EVENT);
-       if (!msg_header) {
-               nlmsg_free(skb);
-               return -ENOMEM;
-       }
-
-       /* fill the data */
-       attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT,
-                          sizeof(struct thermal_genl_event));
-
-       if (!attr) {
-               nlmsg_free(skb);
-               return -EINVAL;
-       }
-
-       thermal_event = nla_data(attr);
-       if (!thermal_event) {
-               nlmsg_free(skb);
-               return -EINVAL;
-       }
-
-       memset(thermal_event, 0, sizeof(struct thermal_genl_event));
-
-       thermal_event->orig = tz->id;
-       thermal_event->event = event;
-
-       /* send multicast genetlink message */
-       genlmsg_end(skb, msg_header);
-
-       result = genlmsg_multicast(&thermal_event_genl_family, skb, 0,
-                                  0, GFP_ATOMIC);
-       if (result)
-               dev_err(&tz->device, "Failed to send netlink event:%d", result);
-
-       return result;
-}
-EXPORT_SYMBOL_GPL(thermal_generate_netlink_event);
-
-static int __init genetlink_init(void)
-{
-       return genl_register_family(&thermal_event_genl_family);
-}
-
-static void genetlink_exit(void)
-{
-       genl_unregister_family(&thermal_event_genl_family);
-}
-#else /* !CONFIG_NET */
-static inline int genetlink_init(void) { return 0; }
-static inline void genetlink_exit(void) {}
-#endif /* !CONFIG_NET */
-
 static int thermal_pm_notify(struct notifier_block *nb,
                             unsigned long mode, void *_unused)
 {
@@ -1607,13 +1514,9 @@ static int __init thermal_init(void)
        if (result)
                goto unregister_governors;
 
-       result = genetlink_init();
-       if (result)
-               goto unregister_class;
-
        result = of_parse_thermal_zones();
        if (result)
-               goto exit_netlink;
+               goto unregister_class;
 
        result = register_pm_notifier(&thermal_pm_nb);
        if (result)
@@ -1622,8 +1525,6 @@ static int __init thermal_init(void)
 
        return 0;
 
-exit_netlink:
-       genetlink_exit();
 unregister_class:
        class_unregister(&thermal_class);
 unregister_governors:
@@ -1636,4 +1537,4 @@ error:
        mutex_destroy(&poweroff_lock);
        return result;
 }
-fs_initcall(thermal_init);
+core_initcall(thermal_init);
index 40524fa..d0bdf1e 100644 (file)
@@ -110,7 +110,6 @@ static struct platform_driver thermal_mmio_driver = {
        .probe = thermal_mmio_probe,
        .driver = {
                .name = "thermal-mmio",
-               .owner = THIS_MODULE,
                .of_match_table = of_match_ptr(thermal_mmio_id_table),
        },
 };
index 8b0ea8c..635cf04 100644 (file)
@@ -2124,10 +2124,11 @@ resubmit:
 /*
  * Start the modem : init the data and start kernel thread
  */
-static int uea_boot(struct uea_softc *sc)
+static int uea_boot(struct uea_softc *sc, struct usb_interface *intf)
 {
-       int ret, size;
        struct intr_pkt *intr;
+       int ret = -ENOMEM;
+       int size;
 
        uea_enters(INS_TO_USBDEV(sc));
 
@@ -2152,6 +2153,11 @@ static int uea_boot(struct uea_softc *sc)
        if (UEA_CHIP_VERSION(sc) == ADI930)
                load_XILINX_firmware(sc);
 
+       if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
+               ret = -ENODEV;
+               goto err0;
+       }
+
        intr = kmalloc(size, GFP_KERNEL);
        if (!intr)
                goto err0;
@@ -2163,8 +2169,7 @@ static int uea_boot(struct uea_softc *sc)
        usb_fill_int_urb(sc->urb_int, sc->usb_dev,
                         usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
                         intr, size, uea_intr, sc,
-                        sc->usb_dev->actconfig->interface[0]->altsetting[0].
-                        endpoint[0].desc.bInterval);
+                        intf->cur_altsetting->endpoint[0].desc.bInterval);
 
        ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
        if (ret < 0) {
@@ -2179,6 +2184,7 @@ static int uea_boot(struct uea_softc *sc)
        sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
        if (IS_ERR(sc->kthread)) {
                uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
+               ret = PTR_ERR(sc->kthread);
                goto err2;
        }
 
@@ -2193,7 +2199,7 @@ err1:
        kfree(intr);
 err0:
        uea_leaves(INS_TO_USBDEV(sc));
-       return -ENOMEM;
+       return ret;
 }
 
 /*
@@ -2548,7 +2554,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
                }
        }
 
-       ret = uea_boot(sc);
+       ret = uea_boot(sc, intf);
        if (ret < 0)
                goto error;
 
index dbea284..4e12a32 100644 (file)
@@ -1275,7 +1275,7 @@ EXPORT_SYMBOL_GPL(usbatm_usb_disconnect);
 
 static int __init usbatm_usb_init(void)
 {
-       if (sizeof(struct usbatm_control) > FIELD_SIZEOF(struct sk_buff, cb)) {
+       if (sizeof(struct usbatm_control) > sizeof_field(struct sk_buff, cb)) {
                printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name);
                return -EIO;
        }
index 87338f9..ed204cb 100644 (file)
@@ -156,7 +156,8 @@ static int usb_conn_probe(struct platform_device *pdev)
 
        info->vbus = devm_regulator_get(dev, "vbus");
        if (IS_ERR(info->vbus)) {
-               dev_err(dev, "failed to get vbus\n");
+               if (PTR_ERR(info->vbus) != -EPROBE_DEFER)
+                       dev_err(dev, "failed to get vbus\n");
                return PTR_ERR(info->vbus);
        }
 
index 281568d..aa45840 100644 (file)
@@ -1409,7 +1409,17 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
        if (usb_endpoint_xfer_control(&urb->ep->desc)) {
                if (hcd->self.uses_pio_for_control)
                        return ret;
-               if (hcd_uses_dma(hcd)) {
+               if (hcd->localmem_pool) {
+                       ret = hcd_alloc_coherent(
+                                       urb->dev->bus, mem_flags,
+                                       &urb->setup_dma,
+                                       (void **)&urb->setup_packet,
+                                       sizeof(struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
+                       if (ret)
+                               return ret;
+                       urb->transfer_flags |= URB_SETUP_MAP_LOCAL;
+               } else if (hcd_uses_dma(hcd)) {
                        if (object_is_on_stack(urb->setup_packet)) {
                                WARN_ONCE(1, "setup packet is on stack\n");
                                return -EAGAIN;
@@ -1424,23 +1434,22 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
                                                urb->setup_dma))
                                return -EAGAIN;
                        urb->transfer_flags |= URB_SETUP_MAP_SINGLE;
-               } else if (hcd->localmem_pool) {
-                       ret = hcd_alloc_coherent(
-                                       urb->dev->bus, mem_flags,
-                                       &urb->setup_dma,
-                                       (void **)&urb->setup_packet,
-                                       sizeof(struct usb_ctrlrequest),
-                                       DMA_TO_DEVICE);
-                       if (ret)
-                               return ret;
-                       urb->transfer_flags |= URB_SETUP_MAP_LOCAL;
                }
        }
 
        dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
        if (urb->transfer_buffer_length != 0
            && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
-               if (hcd_uses_dma(hcd)) {
+               if (hcd->localmem_pool) {
+                       ret = hcd_alloc_coherent(
+                                       urb->dev->bus, mem_flags,
+                                       &urb->transfer_dma,
+                                       &urb->transfer_buffer,
+                                       urb->transfer_buffer_length,
+                                       dir);
+                       if (ret == 0)
+                               urb->transfer_flags |= URB_MAP_LOCAL;
+               } else if (hcd_uses_dma(hcd)) {
                        if (urb->num_sgs) {
                                int n;
 
@@ -1491,15 +1500,6 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
                                else
                                        urb->transfer_flags |= URB_DMA_MAP_SINGLE;
                        }
-               } else if (hcd->localmem_pool) {
-                       ret = hcd_alloc_coherent(
-                                       urb->dev->bus, mem_flags,
-                                       &urb->transfer_dma,
-                                       &urb->transfer_buffer,
-                                       urb->transfer_buffer_length,
-                                       dir);
-                       if (ret == 0)
-                               urb->transfer_flags |= URB_MAP_LOCAL;
                }
                if (ret && (urb->transfer_flags & (URB_SETUP_MAP_SINGLE |
                                URB_SETUP_MAP_LOCAL)))
index 1709895..f229ad6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/sched/mm.h>
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/kcov.h>
 #include <linux/ioctl.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
@@ -5484,6 +5485,8 @@ static void hub_event(struct work_struct *work)
        hub_dev = hub->intfdev;
        intf = to_usb_interface(hub_dev);
 
+       kcov_remote_start_usb((u64)hdev->bus->busnum);
+
        dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
                        hdev->state, hdev->maxchild,
                        /* NOTE: expects max 15 ports... */
@@ -5590,6 +5593,8 @@ out_hdev_lock:
        /* Balance the stuff in kick_hub_wq() and allow autosuspend */
        usb_autopm_put_interface(intf);
        kref_put(&hub->kref, hub_release);
+
+       kcov_remote_stop();
 }
 
 static const struct usb_device_id hub_id_table[] = {
index 0eab79f..da923ec 100644 (file)
@@ -45,6 +45,7 @@ void usb_init_urb(struct urb *urb)
        if (urb) {
                memset(urb, 0, sizeof(*urb));
                kref_init(&urb->kref);
+               INIT_LIST_HEAD(&urb->urb_list);
                INIT_LIST_HEAD(&urb->anchor_list);
        }
 }
index 023f035..294276f 100644 (file)
@@ -29,7 +29,8 @@
 #define PCI_DEVICE_ID_INTEL_BXT_M              0x1aaa
 #define PCI_DEVICE_ID_INTEL_APL                        0x5aaa
 #define PCI_DEVICE_ID_INTEL_KBP                        0xa2b0
-#define PCI_DEVICE_ID_INTEL_CMLH               0x02ee
+#define PCI_DEVICE_ID_INTEL_CMLLP              0x02ee
+#define PCI_DEVICE_ID_INTEL_CMLH               0x06ee
 #define PCI_DEVICE_ID_INTEL_GLK                        0x31aa
 #define PCI_DEVICE_ID_INTEL_CNPLP              0x9dee
 #define PCI_DEVICE_ID_INTEL_CNPH               0xa36e
@@ -308,6 +309,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD),
          (kernel_ulong_t) &dwc3_pci_mrfld_properties, },
 
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLLP),
+         (kernel_ulong_t) &dwc3_pci_intel_properties, },
+
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLH),
          (kernel_ulong_t) &dwc3_pci_intel_properties, },
 
index 3996b9c..fd1b100 100644 (file)
@@ -1117,6 +1117,9 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 void dwc3_ep0_interrupt(struct dwc3 *dwc,
                const struct dwc3_event_depevt *event)
 {
+       struct dwc3_ep  *dep = dwc->eps[event->endpoint_number];
+       u8              cmd;
+
        switch (event->endpoint_event) {
        case DWC3_DEPEVT_XFERCOMPLETE:
                dwc3_ep0_xfer_complete(dwc, event);
@@ -1129,7 +1132,12 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc,
        case DWC3_DEPEVT_XFERINPROGRESS:
        case DWC3_DEPEVT_RXTXFIFOEVT:
        case DWC3_DEPEVT_STREAMEVT:
+               break;
        case DWC3_DEPEVT_EPCMDCMPLT:
+               cmd = DEPEVT_PARAMETER_CMD(event->parameters);
+
+               if (cmd == DWC3_DEPCMD_ENDTRANSFER)
+                       dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
                break;
        }
 }
index a9aba71..0c960a9 100644 (file)
@@ -2491,7 +2491,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
 
        req->request.actual = req->request.length - req->remaining;
 
-       if (!dwc3_gadget_ep_request_completed(req) &&
+       if (!dwc3_gadget_ep_request_completed(req) ||
                        req->num_pending_sgs) {
                __dwc3_gadget_kick_transfer(dep);
                goto out;
@@ -2719,6 +2719,9 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
 
+       if (!interrupt)
+               dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+
        if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A)
                udelay(100);
 }
index 6ce0440..460d5d7 100644 (file)
@@ -621,8 +621,12 @@ static void ecm_disable(struct usb_function *f)
 
        DBG(cdev, "ecm deactivated\n");
 
-       if (ecm->port.in_ep->enabled)
+       if (ecm->port.in_ep->enabled) {
                gether_disconnect(&ecm->port);
+       } else {
+               ecm->port.in_ep->desc = NULL;
+               ecm->port.out_ep->desc = NULL;
+       }
 
        usb_ep_disable(ecm->notify);
        ecm->notify->desc = NULL;
index ce1d023..0bbccac 100644 (file)
@@ -3509,7 +3509,7 @@ static void ffs_free_inst(struct usb_function_instance *f)
 
 static int ffs_set_inst_name(struct usb_function_instance *fi, const char *name)
 {
-       if (strlen(name) >= FIELD_SIZEOF(struct ffs_dev, name))
+       if (strlen(name) >= sizeof_field(struct ffs_dev, name))
                return -ENAMETOOLONG;
        return ffs_name_dev(to_f_fs_opts(fi)->dev, name);
 }
index d48df36..0d8e4a3 100644 (file)
@@ -618,6 +618,7 @@ static void rndis_disable(struct usb_function *f)
        gether_disconnect(&rndis->port);
 
        usb_ep_disable(rndis->notify);
+       rndis->notify->desc = NULL;
 }
 
 /*-------------------------------------------------------------------------*/
index b7d23c4..7a3a29e 100644 (file)
@@ -806,7 +806,7 @@ static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status,
 
 static int xhci_handle_usb2_port_link_resume(struct xhci_port *port,
                                             u32 *status, u32 portsc,
-                                            unsigned long flags)
+                                            unsigned long *flags)
 {
        struct xhci_bus_state *bus_state;
        struct xhci_hcd *xhci;
@@ -860,11 +860,11 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port,
                xhci_test_and_clear_bit(xhci, port, PORT_PLC);
                xhci_set_link_state(xhci, port, XDEV_U0);
 
-               spin_unlock_irqrestore(&xhci->lock, flags);
+               spin_unlock_irqrestore(&xhci->lock, *flags);
                time_left = wait_for_completion_timeout(
                        &bus_state->rexit_done[wIndex],
                        msecs_to_jiffies(XHCI_MAX_REXIT_TIMEOUT_MS));
-               spin_lock_irqsave(&xhci->lock, flags);
+               spin_lock_irqsave(&xhci->lock, *flags);
 
                if (time_left) {
                        slot_id = xhci_find_slot_id_by_port(hcd, xhci,
@@ -920,11 +920,13 @@ static void xhci_get_usb3_port_status(struct xhci_port *port, u32 *status,
 {
        struct xhci_bus_state *bus_state;
        struct xhci_hcd *xhci;
+       struct usb_hcd *hcd;
        u32 link_state;
        u32 portnum;
 
        bus_state = &port->rhub->bus_state;
        xhci = hcd_to_xhci(port->rhub->hcd);
+       hcd = port->rhub->hcd;
        link_state = portsc & PORT_PLS_MASK;
        portnum = port->hcd_portnum;
 
@@ -952,12 +954,20 @@ static void xhci_get_usb3_port_status(struct xhci_port *port, u32 *status,
                        bus_state->suspended_ports &= ~(1 << portnum);
        }
 
+       /* remote wake resume signaling complete */
+       if (bus_state->port_remote_wakeup & (1 << portnum) &&
+           link_state != XDEV_RESUME &&
+           link_state != XDEV_RECOVERY) {
+               bus_state->port_remote_wakeup &= ~(1 << portnum);
+               usb_hcd_end_port_resume(&hcd->self, portnum);
+       }
+
        xhci_hub_report_usb3_link_state(xhci, status, portsc);
        xhci_del_comp_mod_timer(xhci, portsc, portnum);
 }
 
 static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status,
-                                     u32 portsc, unsigned long flags)
+                                     u32 portsc, unsigned long *flags)
 {
        struct xhci_bus_state *bus_state;
        u32 link_state;
@@ -1007,7 +1017,7 @@ static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status,
 static u32 xhci_get_port_status(struct usb_hcd *hcd,
                struct xhci_bus_state *bus_state,
        u16 wIndex, u32 raw_port_status,
-               unsigned long flags)
+               unsigned long *flags)
        __releases(&xhci->lock)
        __acquires(&xhci->lock)
 {
@@ -1130,7 +1140,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                }
                trace_xhci_get_port_status(wIndex, temp);
                status = xhci_get_port_status(hcd, bus_state, wIndex, temp,
-                                             flags);
+                                             &flags);
                if (status == 0xffffffff)
                        goto error;
 
index e16eda6..3b1388f 100644 (file)
@@ -1909,13 +1909,17 @@ no_bw:
        xhci->usb3_rhub.num_ports = 0;
        xhci->num_active_eps = 0;
        kfree(xhci->usb2_rhub.ports);
+       kfree(xhci->usb2_rhub.psi);
        kfree(xhci->usb3_rhub.ports);
+       kfree(xhci->usb3_rhub.psi);
        kfree(xhci->hw_ports);
        kfree(xhci->rh_bw);
        kfree(xhci->ext_caps);
 
        xhci->usb2_rhub.ports = NULL;
+       xhci->usb2_rhub.psi = NULL;
        xhci->usb3_rhub.ports = NULL;
+       xhci->usb3_rhub.psi = NULL;
        xhci->hw_ports = NULL;
        xhci->rh_bw = NULL;
        xhci->ext_caps = NULL;
index a0025d2..2907fe4 100644 (file)
@@ -521,6 +521,18 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
 }
 #endif /* CONFIG_PM */
 
+static void xhci_pci_shutdown(struct usb_hcd *hcd)
+{
+       struct xhci_hcd         *xhci = hcd_to_xhci(hcd);
+       struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
+
+       xhci_shutdown(hcd);
+
+       /* Yet another workaround for spurious wakeups at shutdown with HSW */
+       if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
+               pci_set_power_state(pdev, PCI_D3hot);
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* PCI driver selection metadata; PCI hotplugging uses this */
@@ -556,6 +568,7 @@ static int __init xhci_pci_init(void)
 #ifdef CONFIG_PM
        xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend;
        xhci_pci_hc_driver.pci_resume = xhci_pci_resume;
+       xhci_pci_hc_driver.shutdown = xhci_pci_shutdown;
 #endif
        return pci_register_driver(&xhci_pci_driver);
 }
index 6475c3d..d23f740 100644 (file)
@@ -1628,7 +1628,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
                slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1);
                if (slot_id && xhci->devs[slot_id])
                        xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR;
-               bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
        }
 
        if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) {
@@ -1648,6 +1647,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
                         */
                        bus_state->port_remote_wakeup |= 1 << hcd_portnum;
                        xhci_test_and_clear_bit(xhci, port, PORT_PLC);
+                       usb_hcd_start_port_resume(&hcd->self, hcd_portnum);
                        xhci_set_link_state(xhci, port, XDEV_U0);
                        /* Need to wait until the next link state change
                         * indicates the device is actually in U0.
@@ -1688,7 +1688,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
                if (slot_id && xhci->devs[slot_id])
                        xhci_ring_device(xhci, slot_id);
                if (bus_state->port_remote_wakeup & (1 << hcd_portnum)) {
-                       bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
                        xhci_test_and_clear_bit(xhci, port, PORT_PLC);
                        usb_wakeup_notification(hcd->self.root_hub,
                                        hcd_portnum + 1);
@@ -2382,7 +2381,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
        case COMP_SUCCESS:
                if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
                        break;
-               if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
+               if (xhci->quirks & XHCI_TRUST_TX_LENGTH ||
+                   ep_ring->last_td_was_short)
                        trb_comp_code = COMP_SHORT_PACKET;
                else
                        xhci_warn_ratelimited(xhci,
index 6721d05..dbac0fa 100644 (file)
@@ -770,7 +770,7 @@ static void xhci_stop(struct usb_hcd *hcd)
  *
  * This will only ever be called with the main usb_hcd (the USB3 roothub).
  */
-static void xhci_shutdown(struct usb_hcd *hcd)
+void xhci_shutdown(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
@@ -789,11 +789,8 @@ static void xhci_shutdown(struct usb_hcd *hcd)
        xhci_dbg_trace(xhci, trace_xhci_dbg_init,
                        "xhci_shutdown completed - status = %x",
                        readl(&xhci->op_regs->status));
-
-       /* Yet another workaround for spurious wakeups at shutdown with HSW */
-       if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
-               pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
 }
+EXPORT_SYMBOL_GPL(xhci_shutdown);
 
 #ifdef CONFIG_PM
 static void xhci_save_registers(struct xhci_hcd *xhci)
@@ -973,7 +970,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
 int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
 {
        int                     rc = 0;
-       unsigned int            delay = XHCI_MAX_HALT_USEC;
+       unsigned int            delay = XHCI_MAX_HALT_USEC * 2;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        u32                     command;
        u32                     res;
index dc6f62a..13d8838 100644 (file)
@@ -2050,6 +2050,7 @@ int xhci_start(struct xhci_hcd *xhci);
 int xhci_reset(struct xhci_hcd *xhci);
 int xhci_run(struct usb_hcd *hcd);
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
+void xhci_shutdown(struct usb_hcd *hcd);
 void xhci_init_driver(struct hc_driver *drv,
                      const struct xhci_driver_overrides *over);
 int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
index 6f5edb9..d8d157c 100644 (file)
@@ -669,7 +669,7 @@ static int adu_probe(struct usb_interface *interface,
        init_waitqueue_head(&dev->read_wait);
        init_waitqueue_head(&dev->write_wait);
 
-       res = usb_find_common_endpoints_reverse(&interface->altsetting[0],
+       res = usb_find_common_endpoints_reverse(interface->cur_altsetting,
                        NULL, NULL,
                        &dev->interrupt_in_endpoint,
                        &dev->interrupt_out_endpoint);
index 4afb5dd..e9437a1 100644 (file)
@@ -322,7 +322,7 @@ static int idmouse_probe(struct usb_interface *interface,
        int result;
 
        /* check if we have gotten the data or the hid interface */
-       iface_desc = &interface->altsetting[0];
+       iface_desc = interface->cur_altsetting;
        if (iface_desc->desc.bInterfaceClass != 0x0A)
                return -ENODEV;
 
index ac2b4fc..f48a23a 100644 (file)
@@ -1039,12 +1039,18 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg
 
                mutex_lock(&rp->fetch_lock);
                spin_lock_irqsave(&rp->b_lock, flags);
-               mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE);
-               kfree(rp->b_vec);
-               rp->b_vec  = vec;
-               rp->b_size = size;
-               rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0;
-               rp->cnt_lost = 0;
+               if (rp->mmap_active) {
+                       mon_free_buff(vec, size/CHUNK_SIZE);
+                       kfree(vec);
+                       ret = -EBUSY;
+               } else {
+                       mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE);
+                       kfree(rp->b_vec);
+                       rp->b_vec  = vec;
+                       rp->b_size = size;
+                       rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0;
+                       rp->cnt_lost = 0;
+               }
                spin_unlock_irqrestore(&rp->b_lock, flags);
                mutex_unlock(&rp->fetch_lock);
                }
@@ -1216,13 +1222,21 @@ mon_bin_poll(struct file *file, struct poll_table_struct *wait)
 static void mon_bin_vma_open(struct vm_area_struct *vma)
 {
        struct mon_reader_bin *rp = vma->vm_private_data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rp->b_lock, flags);
        rp->mmap_active++;
+       spin_unlock_irqrestore(&rp->b_lock, flags);
 }
 
 static void mon_bin_vma_close(struct vm_area_struct *vma)
 {
+       unsigned long flags;
+
        struct mon_reader_bin *rp = vma->vm_private_data;
+       spin_lock_irqsave(&rp->b_lock, flags);
        rp->mmap_active--;
+       spin_unlock_irqrestore(&rp->b_lock, flags);
 }
 
 /*
@@ -1234,16 +1248,12 @@ static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf)
        unsigned long offset, chunk_idx;
        struct page *pageptr;
 
-       mutex_lock(&rp->fetch_lock);
        offset = vmf->pgoff << PAGE_SHIFT;
-       if (offset >= rp->b_size) {
-               mutex_unlock(&rp->fetch_lock);
+       if (offset >= rp->b_size)
                return VM_FAULT_SIGBUS;
-       }
        chunk_idx = offset / CHUNK_SIZE;
        pageptr = rp->b_vec[chunk_idx].pg;
        get_page(pageptr);
-       mutex_unlock(&rp->fetch_lock);
        vmf->page = pageptr;
        return 0;
 }
index 8273126..63a00ff 100644 (file)
@@ -169,8 +169,8 @@ EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get);
 void usb_role_switch_put(struct usb_role_switch *sw)
 {
        if (!IS_ERR_OR_NULL(sw)) {
-               put_device(&sw->dev);
                module_put(sw->dev.parent->driver->owner);
+               put_device(&sw->dev);
        }
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_put);
index 48a4392..9690a5f 100644 (file)
@@ -2901,16 +2901,18 @@ static int edge_startup(struct usb_serial *serial)
        response = 0;
 
        if (edge_serial->is_epic) {
+               struct usb_host_interface *alt;
+
+               alt = serial->interface->cur_altsetting;
+
                /* EPIC thing, set up our interrupt polling now and our read
                 * urb, so that the device knows it really is connected. */
                interrupt_in_found = bulk_in_found = bulk_out_found = false;
-               for (i = 0; i < serial->interface->altsetting[0]
-                                               .desc.bNumEndpoints; ++i) {
+               for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
                        struct usb_endpoint_descriptor *endpoint;
                        int buffer_size;
 
-                       endpoint = &serial->interface->altsetting[0].
-                                                       endpoint[i].desc;
+                       endpoint = &alt->endpoint[i].desc;
                        buffer_size = usb_endpoint_maxp(endpoint);
                        if (!interrupt_in_found &&
                            (usb_endpoint_is_int_in(endpoint))) {
index 66a4dcb..f4c2359 100644 (file)
@@ -135,7 +135,8 @@ static int slave_configure(struct scsi_device *sdev)
         * For such controllers we need to make sure the block layer sets
         * up bounce buffers in addressable memory.
         */
-       if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)))
+       if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)) ||
+                       (bus_to_hcd(us->pusb_dev->bus)->localmem_pool != NULL))
                blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH);
 
        /*
index 7ece6ca..91d6227 100644 (file)
@@ -1612,14 +1612,16 @@ struct typec_port *typec_register_port(struct device *parent,
 
        port->sw = typec_switch_get(&port->dev);
        if (IS_ERR(port->sw)) {
+               ret = PTR_ERR(port->sw);
                put_device(&port->dev);
-               return ERR_CAST(port->sw);
+               return ERR_PTR(ret);
        }
 
        port->mux = typec_mux_get(&port->dev, NULL);
        if (IS_ERR(port->mux)) {
+               ret = PTR_ERR(port->mux);
                put_device(&port->dev);
-               return ERR_CAST(port->mux);
+               return ERR_PTR(ret);
        }
 
        ret = device_add(&port->dev);
index 3fa3f72..2056f3f 100644 (file)
@@ -294,8 +294,8 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev,
        irq = pci_irq_vector(pdev, vector);
 
        if (vdev->ctx[vector].trigger) {
-               free_irq(irq, vdev->ctx[vector].trigger);
                irq_bypass_unregister_producer(&vdev->ctx[vector].producer);
+               free_irq(irq, vdev->ctx[vector].trigger);
                kfree(vdev->ctx[vector].name);
                eventfd_ctx_put(vdev->ctx[vector].trigger);
                vdev->ctx[vector].trigger = NULL;
index d864277..2ada8e6 100644 (file)
@@ -294,31 +294,13 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async)
  * Some mappings aren't backed by a struct page, for example an mmap'd
  * MMIO range for our own or another device.  These use a different
  * pfn conversion and shouldn't be tracked as locked pages.
+ * For compound pages, any driver that sets the reserved bit in head
+ * page needs to set the reserved bit in all subpages to be safe.
  */
 static bool is_invalid_reserved_pfn(unsigned long pfn)
 {
-       if (pfn_valid(pfn)) {
-               bool reserved;
-               struct page *tail = pfn_to_page(pfn);
-               struct page *head = compound_head(tail);
-               reserved = !!(PageReserved(head));
-               if (head != tail) {
-                       /*
-                        * "head" is not a dangling pointer
-                        * (compound_head takes care of that)
-                        * but the hugepage may have been split
-                        * from under us (and we may not hold a
-                        * reference count on the head page so it can
-                        * be reused before we run PageReferenced), so
-                        * we've to check PageTail before returning
-                        * what we just read.
-                        */
-                       smp_rmb();
-                       if (PageTail(tail))
-                               return reserved;
-               }
-               return PageReserved(tail);
-       }
+       if (pfn_valid(pfn))
+               return PageReserved(pfn_to_page(pfn));
 
        return true;
 }
index 36ca2cf..f44340b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sched/signal.h>
 #include <linux/interval_tree_generic.h>
 #include <linux/nospec.h>
+#include <linux/kcov.h>
 
 #include "vhost.h"
 
@@ -357,7 +358,9 @@ static int vhost_worker(void *data)
                llist_for_each_entry_safe(work, work_next, node, node) {
                        clear_bit(VHOST_WORK_QUEUED, &work->flags);
                        __set_current_state(TASK_RUNNING);
+                       kcov_remote_start_common(dev->kcov_handle);
                        work->fn(work);
+                       kcov_remote_stop();
                        if (need_resched())
                                schedule();
                }
@@ -546,6 +549,7 @@ long vhost_dev_set_owner(struct vhost_dev *dev)
 
        /* No owner, become one */
        dev->mm = get_task_mm(current);
+       dev->kcov_handle = kcov_common_handle();
        worker = kthread_create(vhost_worker, dev, "vhost-%d", current->pid);
        if (IS_ERR(worker)) {
                err = PTR_ERR(worker);
@@ -571,6 +575,7 @@ err_worker:
        if (dev->mm)
                mmput(dev->mm);
        dev->mm = NULL;
+       dev->kcov_handle = 0;
 err_mm:
        return err;
 }
@@ -682,6 +687,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
        if (dev->worker) {
                kthread_stop(dev->worker);
                dev->worker = NULL;
+               dev->kcov_handle = 0;
        }
        if (dev->mm)
                mmput(dev->mm);
index e9ed272..a123fd7 100644 (file)
@@ -173,6 +173,7 @@ struct vhost_dev {
        int iov_limit;
        int weight;
        int byte_weight;
+       u64 kcov_handle;
 };
 
 bool vhost_exceeds_weight(struct vhost_virtqueue *vq, int pkts, int total_len);
index 50de064..c2d7d57 100644 (file)
@@ -480,7 +480,9 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
                virtio_transport_deliver_tap_pkt(pkt);
 
                /* Only accept correctly addressed packets */
-               if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid)
+               if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid &&
+                   le64_to_cpu(pkt->hdr.dst_cid) ==
+                   vhost_transport_get_local_cid())
                        virtio_transport_recv_pkt(&vhost_transport, pkt);
                else
                        virtio_transport_free_pkt(pkt);
index e05679c..93f995f 100644 (file)
 #define VIRTIO_BALLOON_FREE_PAGE_ALLOC_FLAG (__GFP_NORETRY | __GFP_NOWARN | \
                                             __GFP_NOMEMALLOC)
 /* The order of free page blocks to report to host */
-#define VIRTIO_BALLOON_FREE_PAGE_ORDER (MAX_ORDER - 1)
+#define VIRTIO_BALLOON_HINT_BLOCK_ORDER (MAX_ORDER - 1)
 /* The size of a free page block in bytes */
-#define VIRTIO_BALLOON_FREE_PAGE_SIZE \
-       (1 << (VIRTIO_BALLOON_FREE_PAGE_ORDER + PAGE_SHIFT))
+#define VIRTIO_BALLOON_HINT_BLOCK_BYTES \
+       (1 << (VIRTIO_BALLOON_HINT_BLOCK_ORDER + PAGE_SHIFT))
+#define VIRTIO_BALLOON_HINT_BLOCK_PAGES (1 << VIRTIO_BALLOON_HINT_BLOCK_ORDER)
 
 #ifdef CONFIG_BALLOON_COMPACTION
 static struct vfsmount *balloon_mnt;
@@ -380,7 +381,7 @@ static unsigned long return_free_pages_to_mm(struct virtio_balloon *vb,
                if (!page)
                        break;
                free_pages((unsigned long)page_address(page),
-                          VIRTIO_BALLOON_FREE_PAGE_ORDER);
+                          VIRTIO_BALLOON_HINT_BLOCK_ORDER);
        }
        vb->num_free_page_blocks -= num_returned;
        spin_unlock_irq(&vb->free_page_list_lock);
@@ -582,7 +583,7 @@ static int get_free_page_and_send(struct virtio_balloon *vb)
                ;
 
        page = alloc_pages(VIRTIO_BALLOON_FREE_PAGE_ALLOC_FLAG,
-                          VIRTIO_BALLOON_FREE_PAGE_ORDER);
+                          VIRTIO_BALLOON_HINT_BLOCK_ORDER);
        /*
         * When the allocation returns NULL, it indicates that we have got all
         * the possible free pages, so return -EINTR to stop.
@@ -591,13 +592,13 @@ static int get_free_page_and_send(struct virtio_balloon *vb)
                return -EINTR;
 
        p = page_address(page);
-       sg_init_one(&sg, p, VIRTIO_BALLOON_FREE_PAGE_SIZE);
+       sg_init_one(&sg, p, VIRTIO_BALLOON_HINT_BLOCK_BYTES);
        /* There is always 1 entry reserved for the cmd id to use. */
        if (vq->num_free > 1) {
                err = virtqueue_add_inbuf(vq, &sg, 1, p, GFP_KERNEL);
                if (unlikely(err)) {
                        free_pages((unsigned long)p,
-                                  VIRTIO_BALLOON_FREE_PAGE_ORDER);
+                                  VIRTIO_BALLOON_HINT_BLOCK_ORDER);
                        return err;
                }
                virtqueue_kick(vq);
@@ -610,7 +611,7 @@ static int get_free_page_and_send(struct virtio_balloon *vb)
                 * The vq has no available entry to add this page block, so
                 * just free it.
                 */
-               free_pages((unsigned long)p, VIRTIO_BALLOON_FREE_PAGE_ORDER);
+               free_pages((unsigned long)p, VIRTIO_BALLOON_HINT_BLOCK_ORDER);
        }
 
        return 0;
@@ -721,6 +722,17 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
 
        get_page(newpage); /* balloon reference */
 
+       /*
+         * When we migrate a page to a different zone and adjusted the
+         * managed page count when inflating, we have to fixup the count of
+         * both involved zones.
+         */
+       if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM) &&
+           page_zone(page) != page_zone(newpage)) {
+               adjust_managed_page_count(page, 1);
+               adjust_managed_page_count(newpage, -1);
+       }
+
        /* balloon's page migration 1st step  -- inflate "newpage" */
        spin_lock_irqsave(&vb_dev_info->pages_lock, flags);
        balloon_page_insert(vb_dev_info, newpage);
@@ -765,11 +777,11 @@ static unsigned long shrink_free_pages(struct virtio_balloon *vb,
        unsigned long blocks_to_free, blocks_freed;
 
        pages_to_free = round_up(pages_to_free,
-                                1 << VIRTIO_BALLOON_FREE_PAGE_ORDER);
-       blocks_to_free = pages_to_free >> VIRTIO_BALLOON_FREE_PAGE_ORDER;
+                                VIRTIO_BALLOON_HINT_BLOCK_PAGES);
+       blocks_to_free = pages_to_free / VIRTIO_BALLOON_HINT_BLOCK_PAGES;
        blocks_freed = return_free_pages_to_mm(vb, blocks_to_free);
 
-       return blocks_freed << VIRTIO_BALLOON_FREE_PAGE_ORDER;
+       return blocks_freed * VIRTIO_BALLOON_HINT_BLOCK_PAGES;
 }
 
 static unsigned long leak_balloon_pages(struct virtio_balloon *vb,
@@ -826,7 +838,7 @@ static unsigned long virtio_balloon_shrinker_count(struct shrinker *shrinker,
        unsigned long count;
 
        count = vb->num_pages / VIRTIO_BALLOON_PAGES_PER_PAGE;
-       count += vb->num_free_page_blocks << VIRTIO_BALLOON_FREE_PAGE_ORDER;
+       count += vb->num_free_page_blocks * VIRTIO_BALLOON_HINT_BLOCK_PAGES;
 
        return count;
 }
index 4f2e78a..0c142bc 100644 (file)
@@ -394,7 +394,8 @@ static struct notifier_block xen_memory_nb = {
 #else
 static enum bp_state reserve_additional_memory(void)
 {
-       balloon_stats.target_pages = balloon_stats.current_pages;
+       balloon_stats.target_pages = balloon_stats.current_pages +
+                                    balloon_stats.target_unpopulated;
        return BP_ECANCELED;
 }
 #endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
index 6c88439..499eff7 100644 (file)
@@ -1213,31 +1213,21 @@ void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector)
        notify_remote_via_irq(irq);
 }
 
-static DEFINE_PER_CPU(unsigned, xed_nesting_count);
-
 static void __xen_evtchn_do_upcall(void)
 {
        struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
-       int cpu = get_cpu();
-       unsigned count;
+       int cpu = smp_processor_id();
 
        do {
                vcpu_info->evtchn_upcall_pending = 0;
 
-               if (__this_cpu_inc_return(xed_nesting_count) - 1)
-                       goto out;
-
                xen_evtchn_handle_events(cpu);
 
                BUG_ON(!irqs_disabled());
 
-               count = __this_cpu_read(xed_nesting_count);
-               __this_cpu_write(xed_nesting_count, 0);
-       } while (count != 1 || vcpu_info->evtchn_upcall_pending);
-
-out:
+               virt_rmb(); /* Hypervisor can set upcall pending. */
 
-       put_cpu();
+       } while (vcpu_info->evtchn_upcall_pending);
 }
 
 void xen_evtchn_do_upcall(struct pt_regs *regs)
index 91e44c0..9a3960e 100644 (file)
@@ -81,7 +81,7 @@ void gntdev_add_map(struct gntdev_priv *priv, struct gntdev_grant_map *add);
 
 void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map);
 
-bool gntdev_account_mapped_pages(int count);
+bool gntdev_test_page_count(unsigned int count);
 
 int gntdev_map_grant_pages(struct gntdev_grant_map *map);
 
index 2c4f324..63f0857 100644 (file)
@@ -446,7 +446,7 @@ dmabuf_exp_alloc_backing_storage(struct gntdev_priv *priv, int dmabuf_flags,
 {
        struct gntdev_grant_map *map;
 
-       if (unlikely(count <= 0))
+       if (unlikely(gntdev_test_page_count(count)))
                return ERR_PTR(-EINVAL);
 
        if ((dmabuf_flags & GNTDEV_DMA_FLAG_WC) &&
@@ -459,11 +459,6 @@ dmabuf_exp_alloc_backing_storage(struct gntdev_priv *priv, int dmabuf_flags,
        if (!map)
                return ERR_PTR(-ENOMEM);
 
-       if (unlikely(gntdev_account_mapped_pages(count))) {
-               pr_debug("can't map %d pages: over limit\n", count);
-               gntdev_put_map(NULL, map);
-               return ERR_PTR(-ENOMEM);
-       }
        return map;
 }
 
@@ -771,7 +766,7 @@ long gntdev_ioctl_dmabuf_exp_from_refs(struct gntdev_priv *priv, int use_ptemod,
        if (copy_from_user(&op, u, sizeof(op)) != 0)
                return -EFAULT;
 
-       if (unlikely(op.count <= 0))
+       if (unlikely(gntdev_test_page_count(op.count)))
                return -EINVAL;
 
        refs = kcalloc(op.count, sizeof(*refs), GFP_KERNEL);
@@ -818,7 +813,7 @@ long gntdev_ioctl_dmabuf_imp_to_refs(struct gntdev_priv *priv,
        if (copy_from_user(&op, u, sizeof(op)) != 0)
                return -EFAULT;
 
-       if (unlikely(op.count <= 0))
+       if (unlikely(gntdev_test_page_count(op.count)))
                return -EINVAL;
 
        gntdev_dmabuf = dmabuf_imp_to_refs(priv->dmabuf_priv,
index a04ddf2..4fc83e3 100644 (file)
@@ -55,12 +55,10 @@ MODULE_AUTHOR("Derek G. Murray <Derek.Murray@cl.cam.ac.uk>, "
              "Gerd Hoffmann <kraxel@redhat.com>");
 MODULE_DESCRIPTION("User-space granted page access driver");
 
-static int limit = 1024*1024;
-module_param(limit, int, 0644);
-MODULE_PARM_DESC(limit, "Maximum number of grants that may be mapped by "
-               "the gntdev device");
-
-static atomic_t pages_mapped = ATOMIC_INIT(0);
+static unsigned int limit = 64*1024;
+module_param(limit, uint, 0644);
+MODULE_PARM_DESC(limit,
+       "Maximum number of grants that may be mapped by one mapping request");
 
 static int use_ptemod;
 
@@ -71,9 +69,9 @@ static struct miscdevice gntdev_miscdev;
 
 /* ------------------------------------------------------------------ */
 
-bool gntdev_account_mapped_pages(int count)
+bool gntdev_test_page_count(unsigned int count)
 {
-       return atomic_add_return(count, &pages_mapped) > limit;
+       return !count || count > limit;
 }
 
 static void gntdev_print_maps(struct gntdev_priv *priv,
@@ -114,14 +112,14 @@ static void gntdev_free_map(struct gntdev_grant_map *map)
                gnttab_free_pages(map->count, map->pages);
 
 #ifdef CONFIG_XEN_GRANT_DMA_ALLOC
-       kfree(map->frames);
+       kvfree(map->frames);
 #endif
-       kfree(map->pages);
-       kfree(map->grants);
-       kfree(map->map_ops);
-       kfree(map->unmap_ops);
-       kfree(map->kmap_ops);
-       kfree(map->kunmap_ops);
+       kvfree(map->pages);
+       kvfree(map->grants);
+       kvfree(map->map_ops);
+       kvfree(map->unmap_ops);
+       kvfree(map->kmap_ops);
+       kvfree(map->kunmap_ops);
        kfree(map);
 }
 
@@ -135,12 +133,13 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count,
        if (NULL == add)
                return NULL;
 
-       add->grants    = kcalloc(count, sizeof(add->grants[0]), GFP_KERNEL);
-       add->map_ops   = kcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL);
-       add->unmap_ops = kcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL);
-       add->kmap_ops  = kcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL);
-       add->kunmap_ops = kcalloc(count, sizeof(add->kunmap_ops[0]), GFP_KERNEL);
-       add->pages     = kcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);
+       add->grants    = kvcalloc(count, sizeof(add->grants[0]), GFP_KERNEL);
+       add->map_ops   = kvcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL);
+       add->unmap_ops = kvcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL);
+       add->kmap_ops  = kvcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL);
+       add->kunmap_ops = kvcalloc(count,
+                                  sizeof(add->kunmap_ops[0]), GFP_KERNEL);
+       add->pages     = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);
        if (NULL == add->grants    ||
            NULL == add->map_ops   ||
            NULL == add->unmap_ops ||
@@ -159,8 +158,8 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count,
        if (dma_flags & (GNTDEV_DMA_FLAG_WC | GNTDEV_DMA_FLAG_COHERENT)) {
                struct gnttab_dma_alloc_args args;
 
-               add->frames = kcalloc(count, sizeof(add->frames[0]),
-                                     GFP_KERNEL);
+               add->frames = kvcalloc(count, sizeof(add->frames[0]),
+                                      GFP_KERNEL);
                if (!add->frames)
                        goto err;
 
@@ -241,8 +240,6 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map)
        if (!refcount_dec_and_test(&map->users))
                return;
 
-       atomic_sub(map->count, &pages_mapped);
-
        if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
                notify_remote_via_evtchn(map->notify.event);
                evtchn_put(map->notify.event);
@@ -506,7 +503,6 @@ static const struct mmu_interval_notifier_ops gntdev_mmu_ops = {
 static int gntdev_open(struct inode *inode, struct file *flip)
 {
        struct gntdev_priv *priv;
-       int ret = 0;
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -518,16 +514,12 @@ static int gntdev_open(struct inode *inode, struct file *flip)
 #ifdef CONFIG_XEN_GNTDEV_DMABUF
        priv->dmabuf_priv = gntdev_dmabuf_init(flip);
        if (IS_ERR(priv->dmabuf_priv)) {
-               ret = PTR_ERR(priv->dmabuf_priv);
-               kfree(priv);
-               return ret;
-       }
-#endif
+               int ret = PTR_ERR(priv->dmabuf_priv);
 
-       if (ret) {
                kfree(priv);
                return ret;
        }
+#endif
 
        flip->private_data = priv;
 #ifdef CONFIG_XEN_GRANT_DMA_ALLOC
@@ -573,7 +565,7 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv,
        if (copy_from_user(&op, u, sizeof(op)) != 0)
                return -EFAULT;
        pr_debug("priv %p, add %d\n", priv, op.count);
-       if (unlikely(op.count <= 0))
+       if (unlikely(gntdev_test_page_count(op.count)))
                return -EINVAL;
 
        err = -ENOMEM;
@@ -581,12 +573,6 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv,
        if (!map)
                return err;
 
-       if (unlikely(gntdev_account_mapped_pages(op.count))) {
-               pr_debug("can't map: over limit\n");
-               gntdev_put_map(NULL, map);
-               return err;
-       }
-
        if (copy_from_user(map->grants, &u->refs,
                           sizeof(map->grants[0]) * op.count) != 0) {
                gntdev_put_map(NULL, map);
index 5b47188..c21be6e 100644 (file)
@@ -232,9 +232,16 @@ int xenbus_dev_probe(struct device *_dev)
                return err;
        }
 
+       if (!try_module_get(drv->driver.owner)) {
+               dev_warn(&dev->dev, "failed to acquire module reference on '%s'\n",
+                        drv->driver.name);
+               err = -ESRCH;
+               goto fail;
+       }
+
        err = drv->probe(dev, id);
        if (err)
-               goto fail;
+               goto fail_put;
 
        err = watch_otherend(dev);
        if (err) {
@@ -244,6 +251,8 @@ int xenbus_dev_probe(struct device *_dev)
        }
 
        return 0;
+fail_put:
+       module_put(drv->driver.owner);
 fail:
        xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
        xenbus_switch_state(dev, XenbusStateClosed);
@@ -263,6 +272,8 @@ int xenbus_dev_remove(struct device *_dev)
        if (drv->remove)
                drv->remove(dev);
 
+       module_put(drv->driver.owner);
+
        free_otherend_details(dev);
 
        xenbus_switch_state(dev, XenbusStateClosed);
index 4150280..7503899 100644 (file)
@@ -136,6 +136,9 @@ static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentr
 
        ASSERTCMP(d_inode(dentry), ==, NULL);
 
+       if (flags & LOOKUP_CREATE)
+               return ERR_PTR(-EOPNOTSUPP);
+
        if (dentry->d_name.len >= AFSNAMEMAX) {
                _leave(" = -ENAMETOOLONG");
                return ERR_PTR(-ENAMETOOLONG);
index f532d6d..79bc5f1 100644 (file)
@@ -126,7 +126,7 @@ static int afs_mntpt_set_params(struct fs_context *fc, struct dentry *mntpt)
                if (src_as->cell)
                        ctx->cell = afs_get_cell(src_as->cell);
 
-               if (size > PAGE_SIZE - 1)
+               if (size < 2 || size > PAGE_SIZE - 1)
                        return -EINVAL;
 
                page = read_mapping_page(d_inode(mntpt)->i_mapping, 0, NULL);
@@ -140,7 +140,9 @@ static int afs_mntpt_set_params(struct fs_context *fc, struct dentry *mntpt)
                }
 
                buf = kmap(page);
-               ret = vfs_parse_fs_string(fc, "source", buf, size);
+               ret = -EINVAL;
+               if (buf[size - 1] == '.')
+                       ret = vfs_parse_fs_string(fc, "source", buf, size - 1);
                kunmap(page);
                put_page(page);
                if (ret < 0)
index fba2ec3..468e171 100644 (file)
@@ -213,13 +213,14 @@ static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)
 
        /* Display header on line 1 */
        if (v == &cell->proc_volumes) {
-               seq_puts(m, "USE VID      TY\n");
+               seq_puts(m, "USE VID      TY NAME\n");
                return 0;
        }
 
-       seq_printf(m, "%3d %08llx %s\n",
+       seq_printf(m, "%3d %08llx %s %s\n",
                   atomic_read(&vol->usage), vol->vid,
-                  afs_vol_types[vol->type]);
+                  afs_vol_types[vol->type],
+                  vol->name);
 
        return 0;
 }
index 1686bf1..b7f3cb2 100644 (file)
@@ -32,18 +32,11 @@ static void afs_dec_servers_outstanding(struct afs_net *net)
 struct afs_server *afs_find_server(struct afs_net *net,
                                   const struct sockaddr_rxrpc *srx)
 {
-       const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
        const struct afs_addr_list *alist;
        struct afs_server *server = NULL;
        unsigned int i;
-       bool ipv6 = true;
        int seq = 0, diff;
 
-       if (srx->transport.sin6.sin6_addr.s6_addr32[0] == 0 ||
-           srx->transport.sin6.sin6_addr.s6_addr32[1] == 0 ||
-           srx->transport.sin6.sin6_addr.s6_addr32[2] == htonl(0xffff))
-               ipv6 = false;
-
        rcu_read_lock();
 
        do {
@@ -52,7 +45,8 @@ struct afs_server *afs_find_server(struct afs_net *net,
                server = NULL;
                read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
 
-               if (ipv6) {
+               if (srx->transport.family == AF_INET6) {
+                       const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
                        hlist_for_each_entry_rcu(server, &net->fs_addresses6, addr6_link) {
                                alist = rcu_dereference(server->addresses);
                                for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
@@ -68,15 +62,16 @@ struct afs_server *afs_find_server(struct afs_net *net,
                                }
                        }
                } else {
+                       const struct sockaddr_in *a = &srx->transport.sin, *b;
                        hlist_for_each_entry_rcu(server, &net->fs_addresses4, addr4_link) {
                                alist = rcu_dereference(server->addresses);
                                for (i = 0; i < alist->nr_ipv4; i++) {
-                                       b = &alist->addrs[i].transport.sin6;
-                                       diff = ((u16 __force)a->sin6_port -
-                                               (u16 __force)b->sin6_port);
+                                       b = &alist->addrs[i].transport.sin;
+                                       diff = ((u16 __force)a->sin_port -
+                                               (u16 __force)b->sin_port);
                                        if (diff == 0)
-                                               diff = ((u32 __force)a->sin6_addr.s6_addr32[3] -
-                                                       (u32 __force)b->sin6_addr.s6_addr32[3]);
+                                               diff = ((u32 __force)a->sin_addr.s_addr -
+                                                       (u32 __force)b->sin_addr.s_addr);
                                        if (diff == 0)
                                                goto found;
                                }
index 488641b..7f8a9b3 100644 (file)
@@ -404,6 +404,7 @@ static int afs_test_super(struct super_block *sb, struct fs_context *fc)
        return (as->net_ns == fc->net_ns &&
                as->volume &&
                as->volume->vid == ctx->volume->vid &&
+               as->cell == ctx->cell &&
                !as->dyn_root);
 }
 
@@ -448,7 +449,6 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)
        /* allocate the root inode and dentry */
        if (as->dyn_root) {
                inode = afs_iget_pseudo_dir(sb, true);
-               sb->s_flags     |= SB_RDONLY;
        } else {
                sprintf(sb->s_id, "%llu", as->volume->vid);
                afs_activate_volume(as->volume);
index 8bcec8d..054f97b 100644 (file)
@@ -63,7 +63,7 @@ struct autofs_info {
 
        struct autofs_sb_info *sbi;
        unsigned long last_used;
-       atomic_t count;
+       int count;
 
        kuid_t uid;
        kgid_t gid;
index 91f5787..a1c7701 100644 (file)
@@ -211,7 +211,7 @@ static int autofs_tree_busy(struct vfsmount *mnt,
                        }
                } else {
                        struct autofs_info *ino = autofs_dentry_ino(p);
-                       unsigned int ino_count = atomic_read(&ino->count);
+                       unsigned int ino_count = READ_ONCE(ino->count);
 
                        /* allow for dget above and top is already dgot */
                        if (p == top)
@@ -379,7 +379,7 @@ static struct dentry *should_expire(struct dentry *dentry,
                /* Not a forced expire? */
                if (!(how & AUTOFS_EXP_FORCED)) {
                        /* ref-walk currently on this dentry? */
-                       ino_count = atomic_read(&ino->count) + 1;
+                       ino_count = READ_ONCE(ino->count) + 1;
                        if (d_count(dentry) > ino_count)
                                return NULL;
                }
@@ -396,7 +396,7 @@ static struct dentry *should_expire(struct dentry *dentry,
                /* Not a forced expire? */
                if (!(how & AUTOFS_EXP_FORCED)) {
                        /* ref-walk currently on this dentry? */
-                       ino_count = atomic_read(&ino->count) + 1;
+                       ino_count = READ_ONCE(ino->count) + 1;
                        if (d_count(dentry) > ino_count)
                                return NULL;
                }
index 29abafc..5aaa173 100644 (file)
@@ -569,10 +569,9 @@ static int autofs_dir_symlink(struct inode *dir,
        d_add(dentry, inode);
 
        dget(dentry);
-       atomic_inc(&ino->count);
+       ino->count++;
        p_ino = autofs_dentry_ino(dentry->d_parent);
-       if (p_ino && !IS_ROOT(dentry))
-               atomic_inc(&p_ino->count);
+       p_ino->count++;
 
        dir->i_mtime = current_time(dir);
 
@@ -610,11 +609,9 @@ static int autofs_dir_unlink(struct inode *dir, struct dentry *dentry)
        if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
-       if (atomic_dec_and_test(&ino->count)) {
-               p_ino = autofs_dentry_ino(dentry->d_parent);
-               if (p_ino && !IS_ROOT(dentry))
-                       atomic_dec(&p_ino->count);
-       }
+       ino->count--;
+       p_ino = autofs_dentry_ino(dentry->d_parent);
+       p_ino->count--;
        dput(ino->dentry);
 
        d_inode(dentry)->i_size = 0;
@@ -660,7 +657,6 @@ static void autofs_set_leaf_automount_flags(struct dentry *dentry)
 
 static void autofs_clear_leaf_automount_flags(struct dentry *dentry)
 {
-       struct list_head *d_child;
        struct dentry *parent;
 
        /* flags for dentrys in the root are handled elsewhere */
@@ -673,10 +669,7 @@ static void autofs_clear_leaf_automount_flags(struct dentry *dentry)
        /* only consider parents below dentrys in the root */
        if (IS_ROOT(parent->d_parent))
                return;
-       d_child = &dentry->d_child;
-       /* Set parent managed if it's becoming empty */
-       if (d_child->next == &parent->d_subdirs &&
-           d_child->prev == &parent->d_subdirs)
+       if (autofs_dentry_ino(parent)->count == 2)
                managed_dentry_set_managed(parent);
 }
 
@@ -698,11 +691,10 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
        if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
-       spin_lock(&sbi->lookup_lock);
-       if (!simple_empty(dentry)) {
-               spin_unlock(&sbi->lookup_lock);
+       if (ino->count != 1)
                return -ENOTEMPTY;
-       }
+
+       spin_lock(&sbi->lookup_lock);
        __autofs_add_expiring(dentry);
        d_drop(dentry);
        spin_unlock(&sbi->lookup_lock);
@@ -710,11 +702,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
        if (sbi->version < 5)
                autofs_clear_leaf_automount_flags(dentry);
 
-       if (atomic_dec_and_test(&ino->count)) {
-               p_ino = autofs_dentry_ino(dentry->d_parent);
-               if (p_ino && dentry->d_parent != dentry)
-                       atomic_dec(&p_ino->count);
-       }
+       ino->count--;
+       p_ino = autofs_dentry_ino(dentry->d_parent);
+       p_ino->count--;
        dput(ino->dentry);
        d_inode(dentry)->i_size = 0;
        clear_nlink(d_inode(dentry));
@@ -760,10 +750,9 @@ static int autofs_dir_mkdir(struct inode *dir,
                autofs_set_leaf_automount_flags(dentry);
 
        dget(dentry);
-       atomic_inc(&ino->count);
+       ino->count++;
        p_ino = autofs_dentry_ino(dentry->d_parent);
-       if (p_ino && !IS_ROOT(dentry))
-               atomic_inc(&p_ino->count);
+       p_ino->count++;
        inc_nlink(dir);
        dir->i_mtime = current_time(dir);
 
index 5372eab..ecd8d26 100644 (file)
@@ -404,6 +404,17 @@ static unsigned long total_mapping_size(const struct elf_phdr *cmds, int nr)
                                ELF_PAGESTART(cmds[first_idx].p_vaddr);
 }
 
+static int elf_read(struct file *file, void *buf, size_t len, loff_t pos)
+{
+       ssize_t rv;
+
+       rv = kernel_read(file, buf, len, &pos);
+       if (unlikely(rv != len)) {
+               return (rv < 0) ? rv : -EIO;
+       }
+       return 0;
+}
+
 /**
  * load_elf_phdrs() - load ELF program headers
  * @elf_ex:   ELF header of the binary whose program headers should be loaded
@@ -418,7 +429,6 @@ static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex,
 {
        struct elf_phdr *elf_phdata = NULL;
        int retval, err = -1;
-       loff_t pos = elf_ex->e_phoff;
        unsigned int size;
 
        /*
@@ -439,9 +449,9 @@ static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex,
                goto out;
 
        /* Read in the program headers */
-       retval = kernel_read(elf_file, elf_phdata, size, &pos);
-       if (retval != size) {
-               err = (retval < 0) ? retval : -EIO;
+       retval = elf_read(elf_file, elf_phdata, size, elf_ex->e_phoff);
+       if (retval < 0) {
+               err = retval;
                goto out;
        }
 
@@ -544,7 +554,7 @@ static inline int make_prot(u32 p_flags)
    an ELF header */
 
 static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
-               struct file *interpreter, unsigned long *interp_map_addr,
+               struct file *interpreter,
                unsigned long no_base, struct elf_phdr *interp_elf_phdata)
 {
        struct elf_phdr *eppnt;
@@ -590,8 +600,6 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
                        map_addr = elf_map(interpreter, load_addr + vaddr,
                                        eppnt, elf_prot, elf_type, total_size);
                        total_size = 0;
-                       if (!*interp_map_addr)
-                               *interp_map_addr = map_addr;
                        error = map_addr;
                        if (BAD_ADDR(map_addr))
                                goto out;
@@ -722,7 +730,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
        elf_ppnt = elf_phdata;
        for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
                char *elf_interpreter;
-               loff_t pos;
 
                if (elf_ppnt->p_type != PT_INTERP)
                        continue;
@@ -740,14 +747,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
                if (!elf_interpreter)
                        goto out_free_ph;
 
-               pos = elf_ppnt->p_offset;
-               retval = kernel_read(bprm->file, elf_interpreter,
-                                    elf_ppnt->p_filesz, &pos);
-               if (retval != elf_ppnt->p_filesz) {
-                       if (retval >= 0)
-                               retval = -EIO;
+               retval = elf_read(bprm->file, elf_interpreter, elf_ppnt->p_filesz,
+                                 elf_ppnt->p_offset);
+               if (retval < 0)
                        goto out_free_interp;
-               }
                /* make sure path is NULL terminated */
                retval = -ENOEXEC;
                if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
@@ -766,14 +769,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
                would_dump(bprm, interpreter);
 
                /* Get the exec headers */
-               pos = 0;
-               retval = kernel_read(interpreter, &loc->interp_elf_ex,
-                                    sizeof(loc->interp_elf_ex), &pos);
-               if (retval != sizeof(loc->interp_elf_ex)) {
-                       if (retval >= 0)
-                               retval = -EIO;
+               retval = elf_read(interpreter, &loc->interp_elf_ex,
+                                 sizeof(loc->interp_elf_ex), 0);
+               if (retval < 0)
                        goto out_free_dentry;
-               }
 
                break;
 
@@ -1054,11 +1053,8 @@ out_free_interp:
        }
 
        if (interpreter) {
-               unsigned long interp_map_addr = 0;
-
                elf_entry = load_elf_interp(&loc->interp_elf_ex,
                                            interpreter,
-                                           &interp_map_addr,
                                            load_bias, interp_elf_phdata);
                if (!IS_ERR((void *)elf_entry)) {
                        /*
@@ -1179,11 +1175,10 @@ static int load_elf_library(struct file *file)
        unsigned long elf_bss, bss, len;
        int retval, error, i, j;
        struct elfhdr elf_ex;
-       loff_t pos = 0;
 
        error = -ENOEXEC;
-       retval = kernel_read(file, &elf_ex, sizeof(elf_ex), &pos);
-       if (retval != sizeof(elf_ex))
+       retval = elf_read(file, &elf_ex, sizeof(elf_ex), 0);
+       if (retval < 0)
                goto out;
 
        if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
@@ -1208,9 +1203,8 @@ static int load_elf_library(struct file *file)
 
        eppnt = elf_phdata;
        error = -ENOEXEC;
-       pos =  elf_ex.e_phoff;
-       retval = kernel_read(file, eppnt, j, &pos);
-       if (retval != j)
+       retval = elf_read(file, eppnt, j, elf_ex.e_phoff);
+       if (retval < 0)
                goto out_free_ph;
 
        for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
index ee63c27..69bf2fb 100644 (file)
@@ -1531,7 +1531,7 @@ rescan:
                ret = blk_add_partitions(disk, bdev);
                if (ret == -EAGAIN)
                        goto rescan;
-       } else {
+       } else if (invalidate) {
                /*
                 * Tell userspace that the media / partition table may have
                 * changed.
index 75b6d10..575636f 100644 (file)
@@ -7,6 +7,7 @@ config BTRFS_FS
        select LIBCRC32C
        select CRYPTO_XXHASH
        select CRYPTO_SHA256
+       select CRYPTO_BLAKE2B
        select ZLIB_INFLATE
        select ZLIB_DEFLATE
        select LZO_COMPRESS
index b2ec29e..73f24f3 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/ceph/ceph_debug.h>
 
+#include <linux/fs_context.h>
 #include "super.h"
 #include "cache.h"
 
@@ -49,7 +50,7 @@ void ceph_fscache_unregister(void)
        fscache_unregister_netfs(&ceph_cache_netfs);
 }
 
-int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
+int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc)
 {
        const struct ceph_fsid *fsid = &fsc->client->fsid;
        const char *fscache_uniq = fsc->mount_options->fscache_uniq;
@@ -66,8 +67,8 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
                if (uniq_len && memcmp(ent->uniquifier, fscache_uniq, uniq_len))
                        continue;
 
-               pr_err("fscache cookie already registered for fsid %pU\n", fsid);
-               pr_err("  use fsc=%%s mount option to specify a uniquifier\n");
+               errorf(fc, "ceph: fscache cookie already registered for fsid %pU, use fsc=<uniquifier> option",
+                      fsid);
                err = -EBUSY;
                goto out_unlock;
        }
@@ -95,7 +96,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
                list_add_tail(&ent->list, &ceph_fscache_list);
        } else {
                kfree(ent);
-               pr_err("unable to register fscache cookie for fsid %pU\n",
+               errorf(fc, "ceph: unable to register fscache cookie for fsid %pU",
                       fsid);
                /* all other fs ignore this error */
        }
index e486fac..89dbdd1 100644 (file)
@@ -16,7 +16,7 @@ extern struct fscache_netfs ceph_cache_netfs;
 int ceph_fscache_register(void);
 void ceph_fscache_unregister(void);
 
-int ceph_fscache_register_fs(struct ceph_fs_client* fsc);
+int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc);
 void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc);
 
 void ceph_fscache_register_inode_cookie(struct inode *inode);
@@ -88,7 +88,8 @@ static inline void ceph_fscache_unregister(void)
 {
 }
 
-static inline int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
+static inline int ceph_fscache_register_fs(struct ceph_fs_client* fsc,
+                                          struct fs_context *fc)
 {
        return 0;
 }
index f5a3891..9d09bb5 100644 (file)
@@ -1011,18 +1011,13 @@ static int __ceph_is_single_caps(struct ceph_inode_info *ci)
        return rb_first(&ci->i_caps) == rb_last(&ci->i_caps);
 }
 
-static int __ceph_is_any_caps(struct ceph_inode_info *ci)
-{
-       return !RB_EMPTY_ROOT(&ci->i_caps);
-}
-
 int ceph_is_any_caps(struct inode *inode)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        int ret;
 
        spin_lock(&ci->i_ceph_lock);
-       ret = __ceph_is_any_caps(ci);
+       ret = __ceph_is_any_real_caps(ci);
        spin_unlock(&ci->i_ceph_lock);
 
        return ret;
@@ -1099,15 +1094,16 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
        if (removed)
                ceph_put_cap(mdsc, cap);
 
-       /* when reconnect denied, we remove session caps forcibly,
-        * i_wr_ref can be non-zero. If there are ongoing write,
-        * keep i_snap_realm.
-        */
-       if (!__ceph_is_any_caps(ci) && ci->i_wr_ref == 0 && ci->i_snap_realm)
-               drop_inode_snap_realm(ci);
+       if (!__ceph_is_any_real_caps(ci)) {
+               /* when reconnect denied, we remove session caps forcibly,
+                * i_wr_ref can be non-zero. If there are ongoing write,
+                * keep i_snap_realm.
+                */
+               if (ci->i_wr_ref == 0 && ci->i_snap_realm)
+                       drop_inode_snap_realm(ci);
 
-       if (!__ceph_is_any_real_caps(ci))
                __cap_delay_cancel(mdsc, ci);
+       }
 }
 
 struct cap_msg_args {
@@ -2764,7 +2760,19 @@ int ceph_get_caps(struct file *filp, int need, int want,
                if (ret == -EAGAIN)
                        continue;
                if (!ret) {
+                       struct ceph_mds_client *mdsc = fsc->mdsc;
+                       struct cap_wait cw;
                        DEFINE_WAIT_FUNC(wait, woken_wake_function);
+
+                       cw.ino = inode->i_ino;
+                       cw.tgid = current->tgid;
+                       cw.need = need;
+                       cw.want = want;
+
+                       spin_lock(&mdsc->caps_list_lock);
+                       list_add(&cw.list, &mdsc->cap_wait_list);
+                       spin_unlock(&mdsc->caps_list_lock);
+
                        add_wait_queue(&ci->i_cap_wq, &wait);
 
                        flags |= NON_BLOCKING;
@@ -2778,6 +2786,11 @@ int ceph_get_caps(struct file *filp, int need, int want,
                        }
 
                        remove_wait_queue(&ci->i_cap_wq, &wait);
+
+                       spin_lock(&mdsc->caps_list_lock);
+                       list_del(&cw.list);
+                       spin_unlock(&mdsc->caps_list_lock);
+
                        if (ret == -EAGAIN)
                                continue;
                }
@@ -2928,7 +2941,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
                                ci->i_head_snapc = NULL;
                        }
                        /* see comment in __ceph_remove_cap() */
-                       if (!__ceph_is_any_caps(ci) && ci->i_snap_realm)
+                       if (!__ceph_is_any_real_caps(ci) && ci->i_snap_realm)
                                drop_inode_snap_realm(ci);
                }
        spin_unlock(&ci->i_ceph_lock);
index facb387..c281f32 100644 (file)
@@ -139,6 +139,7 @@ static int caps_show(struct seq_file *s, void *p)
        struct ceph_fs_client *fsc = s->private;
        struct ceph_mds_client *mdsc = fsc->mdsc;
        int total, avail, used, reserved, min, i;
+       struct cap_wait *cw;
 
        ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
        seq_printf(s, "total\t\t%d\n"
@@ -166,6 +167,18 @@ static int caps_show(struct seq_file *s, void *p)
        }
        mutex_unlock(&mdsc->mutex);
 
+       seq_printf(s, "\n\nWaiters:\n--------\n");
+       seq_printf(s, "tgid         ino                need             want\n");
+       seq_printf(s, "-----------------------------------------------------\n");
+
+       spin_lock(&mdsc->caps_list_lock);
+       list_for_each_entry(cw, &mdsc->cap_wait_list, list) {
+               seq_printf(s, "%-13d0x%-17lx%-17s%-17s\n", cw->tgid, cw->ino,
+                               ceph_cap_string(cw->need),
+                               ceph_cap_string(cw->want));
+       }
+       spin_unlock(&mdsc->caps_list_lock);
+
        return 0;
 }
 
index a516329..374db1b 100644 (file)
@@ -2015,7 +2015,7 @@ void ceph_reclaim_caps_nr(struct ceph_mds_client *mdsc, int nr)
        if (!nr)
                return;
        val = atomic_add_return(nr, &mdsc->cap_reclaim_pending);
-       if (!(val % CEPH_CAPS_PER_RELEASE)) {
+       if ((val % CEPH_CAPS_PER_RELEASE) < nr) {
                atomic_set(&mdsc->cap_reclaim_pending, 0);
                ceph_queue_cap_reclaim_work(mdsc);
        }
@@ -2032,12 +2032,13 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
        struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
        struct ceph_mount_options *opt = req->r_mdsc->fsc->mount_options;
        size_t size = sizeof(struct ceph_mds_reply_dir_entry);
-       int order, num_entries;
+       unsigned int num_entries;
+       int order;
 
        spin_lock(&ci->i_ceph_lock);
        num_entries = ci->i_files + ci->i_subdirs;
        spin_unlock(&ci->i_ceph_lock);
-       num_entries = max(num_entries, 1);
+       num_entries = max(num_entries, 1U);
        num_entries = min(num_entries, opt->max_readdir);
 
        order = get_order(size * num_entries);
@@ -2182,13 +2183,17 @@ retry:
        }
        base = ceph_ino(d_inode(temp));
        rcu_read_unlock();
-       if (pos < 0 || read_seqretry(&rename_lock, seq)) {
-               pr_err("build_path did not end path lookup where "
-                      "expected, pos is %d\n", pos);
-               /* presumably this is only possible if racing with a
-                  rename of one of the parent directories (we can not
-                  lock the dentries above us to prevent this, but
-                  retrying should be harmless) */
+
+       if (read_seqretry(&rename_lock, seq))
+               goto retry;
+
+       if (pos < 0) {
+               /*
+                * A rename didn't occur, but somehow we didn't end up where
+                * we thought we would. Throw a warning and try again.
+                */
+               pr_warn("build_path did not end path lookup where "
+                       "expected, pos is %d\n", pos);
                goto retry;
        }
 
@@ -2345,6 +2350,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        head->op = cpu_to_le32(req->r_op);
        head->caller_uid = cpu_to_le32(from_kuid(&init_user_ns, req->r_uid));
        head->caller_gid = cpu_to_le32(from_kgid(&init_user_ns, req->r_gid));
+       head->ino = 0;
        head->args = req->r_args;
 
        ceph_encode_filepath(&p, end, ino1, path1);
@@ -4163,6 +4169,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
        INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work);
        mdsc->last_renew_caps = jiffies;
        INIT_LIST_HEAD(&mdsc->cap_delay_list);
+       INIT_LIST_HEAD(&mdsc->cap_wait_list);
        spin_lock_init(&mdsc->cap_delay_lock);
        INIT_LIST_HEAD(&mdsc->snap_flush_list);
        spin_lock_init(&mdsc->snap_flush_lock);
index 5cd131b..14c7e8c 100644 (file)
@@ -340,6 +340,14 @@ struct ceph_quotarealm_inode {
        struct inode *inode;
 };
 
+struct cap_wait {
+       struct list_head        list;
+       unsigned long           ino;
+       pid_t                   tgid;
+       int                     need;
+       int                     want;
+};
+
 /*
  * mds client state
  */
@@ -416,6 +424,7 @@ struct ceph_mds_client {
        spinlock_t      caps_list_lock;
        struct          list_head caps_list; /* unused (reserved or
                                                unreserved) */
+       struct          list_head cap_wait_list;
        int             caps_total_count;    /* total caps allocated */
        int             caps_use_count;      /* in use */
        int             caps_use_max;        /* max used caps */
index ce2d00d..471bac3 100644 (file)
@@ -20,7 +20,7 @@
 int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
 {
        int n = 0;
-       int i;
+       int i, j;
 
        /* special case for one mds */
        if (1 == m->m_num_mds && m->m_info[0].state > 0)
@@ -35,9 +35,12 @@ int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
 
        /* pick */
        n = prandom_u32() % n;
-       for (i = 0; n > 0; i++, n--)
-               while (m->m_info[i].state <= 0)
-                       i++;
+       for (j = 0, i = 0; i < m->m_num_mds; i++) {
+               if (m->m_info[i].state > 0)
+                       j++;
+               if (j > n)
+                       break;
+       }
 
        return i;
 }
@@ -155,6 +158,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                void *pexport_targets = NULL;
                struct ceph_timespec laggy_since;
                struct ceph_mds_info *info;
+               bool laggy;
 
                ceph_decode_need(p, end, sizeof(u64) + 1, bad);
                global_id = ceph_decode_64(p);
@@ -187,6 +191,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                if (err)
                        goto corrupt;
                ceph_decode_copy(p, &laggy_since, sizeof(laggy_since));
+               laggy = laggy_since.tv_sec != 0 || laggy_since.tv_nsec != 0;
                *p += sizeof(u32);
                ceph_decode_32_safe(p, end, namelen, bad);
                *p += namelen;
@@ -204,10 +209,11 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                        *p = info_end;
                }
 
-               dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n",
+               dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s%s\n",
                     i+1, n, global_id, mds, inc,
                     ceph_pr_addr(&addr),
-                    ceph_mds_state_name(state));
+                    ceph_mds_state_name(state),
+                    laggy ? "(laggy)" : "");
 
                if (mds < 0 || state <= 0)
                        continue;
@@ -227,8 +233,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                info->global_id = global_id;
                info->state = state;
                info->addr = addr;
-               info->laggy = (laggy_since.tv_sec != 0 ||
-                              laggy_since.tv_nsec != 0);
+               info->laggy = laggy;
                info->num_export_targets = num_export_targets;
                if (num_export_targets) {
                        info->export_targets = kcalloc(num_export_targets,
@@ -352,6 +357,8 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                m->m_damaged = false;
        }
 bad_ext:
+       dout("mdsmap_decode m_enabled: %d, m_damaged: %d, m_num_laggy: %d\n",
+            !!m->m_enabled, !!m->m_damaged, m->m_num_laggy);
        *p = end;
        dout("mdsmap_decode success epoch %u\n", m->m_epoch);
        return m;
index b47f43f..29a795f 100644 (file)
@@ -9,7 +9,8 @@
 #include <linux/in6.h>
 #include <linux/module.h>
 #include <linux/mount.h>
-#include <linux/parser.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
@@ -138,280 +139,310 @@ enum {
        Opt_readdir_max_entries,
        Opt_readdir_max_bytes,
        Opt_congestion_kb,
-       Opt_last_int,
        /* int args above */
        Opt_snapdirname,
        Opt_mds_namespace,
-       Opt_fscache_uniq,
        Opt_recover_session,
-       Opt_last_string,
+       Opt_source,
        /* string args above */
        Opt_dirstat,
-       Opt_nodirstat,
        Opt_rbytes,
-       Opt_norbytes,
        Opt_asyncreaddir,
-       Opt_noasyncreaddir,
        Opt_dcache,
-       Opt_nodcache,
        Opt_ino32,
-       Opt_noino32,
        Opt_fscache,
-       Opt_nofscache,
        Opt_poolperm,
-       Opt_nopoolperm,
        Opt_require_active_mds,
-       Opt_norequire_active_mds,
-#ifdef CONFIG_CEPH_FS_POSIX_ACL
        Opt_acl,
-#endif
-       Opt_noacl,
        Opt_quotadf,
-       Opt_noquotadf,
        Opt_copyfrom,
-       Opt_nocopyfrom,
 };
 
-static match_table_t fsopt_tokens = {
-       {Opt_wsize, "wsize=%d"},
-       {Opt_rsize, "rsize=%d"},
-       {Opt_rasize, "rasize=%d"},
-       {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"},
-       {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"},
-       {Opt_caps_max, "caps_max=%d"},
-       {Opt_readdir_max_entries, "readdir_max_entries=%d"},
-       {Opt_readdir_max_bytes, "readdir_max_bytes=%d"},
-       {Opt_congestion_kb, "write_congestion_kb=%d"},
-       /* int args above */
-       {Opt_snapdirname, "snapdirname=%s"},
-       {Opt_mds_namespace, "mds_namespace=%s"},
-       {Opt_recover_session, "recover_session=%s"},
-       {Opt_fscache_uniq, "fsc=%s"},
-       /* string args above */
-       {Opt_dirstat, "dirstat"},
-       {Opt_nodirstat, "nodirstat"},
-       {Opt_rbytes, "rbytes"},
-       {Opt_norbytes, "norbytes"},
-       {Opt_asyncreaddir, "asyncreaddir"},
-       {Opt_noasyncreaddir, "noasyncreaddir"},
-       {Opt_dcache, "dcache"},
-       {Opt_nodcache, "nodcache"},
-       {Opt_ino32, "ino32"},
-       {Opt_noino32, "noino32"},
-       {Opt_fscache, "fsc"},
-       {Opt_nofscache, "nofsc"},
-       {Opt_poolperm, "poolperm"},
-       {Opt_nopoolperm, "nopoolperm"},
-       {Opt_require_active_mds, "require_active_mds"},
-       {Opt_norequire_active_mds, "norequire_active_mds"},
-#ifdef CONFIG_CEPH_FS_POSIX_ACL
-       {Opt_acl, "acl"},
-#endif
-       {Opt_noacl, "noacl"},
-       {Opt_quotadf, "quotadf"},
-       {Opt_noquotadf, "noquotadf"},
-       {Opt_copyfrom, "copyfrom"},
-       {Opt_nocopyfrom, "nocopyfrom"},
-       {-1, NULL}
+enum ceph_recover_session_mode {
+       ceph_recover_session_no,
+       ceph_recover_session_clean
+};
+
+static const struct fs_parameter_enum ceph_mount_param_enums[] = {
+       { Opt_recover_session,  "no",           ceph_recover_session_no },
+       { Opt_recover_session,  "clean",        ceph_recover_session_clean },
+       {}
+};
+
+static const struct fs_parameter_spec ceph_mount_param_specs[] = {
+       fsparam_flag_no ("acl",                         Opt_acl),
+       fsparam_flag_no ("asyncreaddir",                Opt_asyncreaddir),
+       fsparam_s32     ("caps_max",                    Opt_caps_max),
+       fsparam_u32     ("caps_wanted_delay_max",       Opt_caps_wanted_delay_max),
+       fsparam_u32     ("caps_wanted_delay_min",       Opt_caps_wanted_delay_min),
+       fsparam_u32     ("write_congestion_kb",         Opt_congestion_kb),
+       fsparam_flag_no ("copyfrom",                    Opt_copyfrom),
+       fsparam_flag_no ("dcache",                      Opt_dcache),
+       fsparam_flag_no ("dirstat",                     Opt_dirstat),
+       __fsparam       (fs_param_is_string, "fsc",     Opt_fscache,
+                        fs_param_neg_with_no | fs_param_v_optional),
+       fsparam_flag_no ("ino32",                       Opt_ino32),
+       fsparam_string  ("mds_namespace",               Opt_mds_namespace),
+       fsparam_flag_no ("poolperm",                    Opt_poolperm),
+       fsparam_flag_no ("quotadf",                     Opt_quotadf),
+       fsparam_u32     ("rasize",                      Opt_rasize),
+       fsparam_flag_no ("rbytes",                      Opt_rbytes),
+       fsparam_u32     ("readdir_max_bytes",           Opt_readdir_max_bytes),
+       fsparam_u32     ("readdir_max_entries",         Opt_readdir_max_entries),
+       fsparam_enum    ("recover_session",             Opt_recover_session),
+       fsparam_flag_no ("require_active_mds",          Opt_require_active_mds),
+       fsparam_u32     ("rsize",                       Opt_rsize),
+       fsparam_string  ("snapdirname",                 Opt_snapdirname),
+       fsparam_string  ("source",                      Opt_source),
+       fsparam_u32     ("wsize",                       Opt_wsize),
+       {}
+};
+
+static const struct fs_parameter_description ceph_mount_parameters = {
+       .name           = "ceph",
+       .specs          = ceph_mount_param_specs,
+       .enums          = ceph_mount_param_enums,
 };
 
-static int parse_fsopt_token(char *c, void *private)
+struct ceph_parse_opts_ctx {
+       struct ceph_options             *copts;
+       struct ceph_mount_options       *opts;
+};
+
+/*
+ * Parse the source parameter.  Distinguish the server list from the path.
+ * Internally we do not include the leading '/' in the path.
+ *
+ * The source will look like:
+ *     <server_spec>[,<server_spec>...]:[<path>]
+ * where
+ *     <server_spec> is <ip>[:<port>]
+ *     <path> is optional, but if present must begin with '/'
+ */
+static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc)
 {
-       struct ceph_mount_options *fsopt = private;
-       substring_t argstr[MAX_OPT_ARGS];
-       int token, intval, ret;
+       struct ceph_parse_opts_ctx *pctx = fc->fs_private;
+       struct ceph_mount_options *fsopt = pctx->opts;
+       char *dev_name = param->string, *dev_name_end;
+       int ret;
 
-       token = match_token((char *)c, fsopt_tokens, argstr);
-       if (token < 0)
-               return -EINVAL;
+       dout("%s '%s'\n", __func__, dev_name);
+       if (!dev_name || !*dev_name)
+               return invalf(fc, "ceph: Empty source");
 
-       if (token < Opt_last_int) {
-               ret = match_int(&argstr[0], &intval);
-               if (ret < 0) {
-                       pr_err("bad option arg (not int) at '%s'\n", c);
-                       return ret;
+       dev_name_end = strchr(dev_name, '/');
+       if (dev_name_end) {
+               if (strlen(dev_name_end) > 1) {
+                       kfree(fsopt->server_path);
+                       fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
+                       if (!fsopt->server_path)
+                               return -ENOMEM;
                }
-               dout("got int token %d val %d\n", token, intval);
-       } else if (token > Opt_last_int && token < Opt_last_string) {
-               dout("got string token %d val %s\n", token,
-                    argstr[0].from);
        } else {
-               dout("got token %d\n", token);
+               dev_name_end = dev_name + strlen(dev_name);
        }
 
+       dev_name_end--;         /* back up to ':' separator */
+       if (dev_name_end < dev_name || *dev_name_end != ':')
+               return invalf(fc, "ceph: No path or : separator in source");
+
+       dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
+       if (fsopt->server_path)
+               dout("server path '%s'\n", fsopt->server_path);
+
+       ret = ceph_parse_mon_ips(param->string, dev_name_end - dev_name,
+                                pctx->copts, fc);
+       if (ret)
+               return ret;
+
+       fc->source = param->string;
+       param->string = NULL;
+       return 0;
+}
+
+static int ceph_parse_mount_param(struct fs_context *fc,
+                                 struct fs_parameter *param)
+{
+       struct ceph_parse_opts_ctx *pctx = fc->fs_private;
+       struct ceph_mount_options *fsopt = pctx->opts;
+       struct fs_parse_result result;
+       unsigned int mode;
+       int token, ret;
+
+       ret = ceph_parse_param(param, pctx->copts, fc);
+       if (ret != -ENOPARAM)
+               return ret;
+
+       token = fs_parse(fc, &ceph_mount_parameters, param, &result);
+       dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
+       if (token < 0)
+               return token;
+
        switch (token) {
        case Opt_snapdirname:
                kfree(fsopt->snapdir_name);
-               fsopt->snapdir_name = kstrndup(argstr[0].from,
-                                              argstr[0].to-argstr[0].from,
-                                              GFP_KERNEL);
-               if (!fsopt->snapdir_name)
-                       return -ENOMEM;
+               fsopt->snapdir_name = param->string;
+               param->string = NULL;
                break;
        case Opt_mds_namespace:
                kfree(fsopt->mds_namespace);
-               fsopt->mds_namespace = kstrndup(argstr[0].from,
-                                               argstr[0].to-argstr[0].from,
-                                               GFP_KERNEL);
-               if (!fsopt->mds_namespace)
-                       return -ENOMEM;
+               fsopt->mds_namespace = param->string;
+               param->string = NULL;
                break;
        case Opt_recover_session:
-               if (!strncmp(argstr[0].from, "no",
-                            argstr[0].to - argstr[0].from)) {
+               mode = result.uint_32;
+               if (mode == ceph_recover_session_no)
                        fsopt->flags &= ~CEPH_MOUNT_OPT_CLEANRECOVER;
-               } else if (!strncmp(argstr[0].from, "clean",
-                                   argstr[0].to - argstr[0].from)) {
+               else if (mode == ceph_recover_session_clean)
                        fsopt->flags |= CEPH_MOUNT_OPT_CLEANRECOVER;
-               } else {
-                       return -EINVAL;
-               }
-               break;
-       case Opt_fscache_uniq:
-#ifdef CONFIG_CEPH_FSCACHE
-               kfree(fsopt->fscache_uniq);
-               fsopt->fscache_uniq = kstrndup(argstr[0].from,
-                                              argstr[0].to-argstr[0].from,
-                                              GFP_KERNEL);
-               if (!fsopt->fscache_uniq)
-                       return -ENOMEM;
-               fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE;
+               else
+                       BUG();
                break;
-#else
-               pr_err("fscache support is disabled\n");
-               return -EINVAL;
-#endif
+       case Opt_source:
+               if (fc->source)
+                       return invalf(fc, "ceph: Multiple sources specified");
+               return ceph_parse_source(param, fc);
        case Opt_wsize:
-               if (intval < (int)PAGE_SIZE || intval > CEPH_MAX_WRITE_SIZE)
-                       return -EINVAL;
-               fsopt->wsize = ALIGN(intval, PAGE_SIZE);
+               if (result.uint_32 < PAGE_SIZE ||
+                   result.uint_32 > CEPH_MAX_WRITE_SIZE)
+                       goto out_of_range;
+               fsopt->wsize = ALIGN(result.uint_32, PAGE_SIZE);
                break;
        case Opt_rsize:
-               if (intval < (int)PAGE_SIZE || intval > CEPH_MAX_READ_SIZE)
-                       return -EINVAL;
-               fsopt->rsize = ALIGN(intval, PAGE_SIZE);
+               if (result.uint_32 < PAGE_SIZE ||
+                   result.uint_32 > CEPH_MAX_READ_SIZE)
+                       goto out_of_range;
+               fsopt->rsize = ALIGN(result.uint_32, PAGE_SIZE);
                break;
        case Opt_rasize:
-               if (intval < 0)
-                       return -EINVAL;
-               fsopt->rasize = ALIGN(intval, PAGE_SIZE);
+               fsopt->rasize = ALIGN(result.uint_32, PAGE_SIZE);
                break;
        case Opt_caps_wanted_delay_min:
-               if (intval < 1)
-                       return -EINVAL;
-               fsopt->caps_wanted_delay_min = intval;
+               if (result.uint_32 < 1)
+                       goto out_of_range;
+               fsopt->caps_wanted_delay_min = result.uint_32;
                break;
        case Opt_caps_wanted_delay_max:
-               if (intval < 1)
-                       return -EINVAL;
-               fsopt->caps_wanted_delay_max = intval;
+               if (result.uint_32 < 1)
+                       goto out_of_range;
+               fsopt->caps_wanted_delay_max = result.uint_32;
                break;
        case Opt_caps_max:
-               if (intval < 0)
-                       return -EINVAL;
-               fsopt->caps_max = intval;
+               if (result.int_32 < 0)
+                       goto out_of_range;
+               fsopt->caps_max = result.int_32;
                break;
        case Opt_readdir_max_entries:
-               if (intval < 1)
-                       return -EINVAL;
-               fsopt->max_readdir = intval;
+               if (result.uint_32 < 1)
+                       goto out_of_range;
+               fsopt->max_readdir = result.uint_32;
                break;
        case Opt_readdir_max_bytes:
-               if (intval < (int)PAGE_SIZE && intval != 0)
-                       return -EINVAL;
-               fsopt->max_readdir_bytes = intval;
+               if (result.uint_32 < PAGE_SIZE && result.uint_32 != 0)
+                       goto out_of_range;
+               fsopt->max_readdir_bytes = result.uint_32;
                break;
        case Opt_congestion_kb:
-               if (intval < 1024) /* at least 1M */
-                       return -EINVAL;
-               fsopt->congestion_kb = intval;
+               if (result.uint_32 < 1024) /* at least 1M */
+                       goto out_of_range;
+               fsopt->congestion_kb = result.uint_32;
                break;
        case Opt_dirstat:
-               fsopt->flags |= CEPH_MOUNT_OPT_DIRSTAT;
-               break;
-       case Opt_nodirstat:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_DIRSTAT;
+               if (!result.negated)
+                       fsopt->flags |= CEPH_MOUNT_OPT_DIRSTAT;
+               else
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_DIRSTAT;
                break;
        case Opt_rbytes:
-               fsopt->flags |= CEPH_MOUNT_OPT_RBYTES;
-               break;
-       case Opt_norbytes:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_RBYTES;
+               if (!result.negated)
+                       fsopt->flags |= CEPH_MOUNT_OPT_RBYTES;
+               else
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_RBYTES;
                break;
        case Opt_asyncreaddir:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_NOASYNCREADDIR;
-               break;
-       case Opt_noasyncreaddir:
-               fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR;
+               if (!result.negated)
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_NOASYNCREADDIR;
+               else
+                       fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR;
                break;
        case Opt_dcache:
-               fsopt->flags |= CEPH_MOUNT_OPT_DCACHE;
-               break;
-       case Opt_nodcache:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_DCACHE;
+               if (!result.negated)
+                       fsopt->flags |= CEPH_MOUNT_OPT_DCACHE;
+               else
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_DCACHE;
                break;
        case Opt_ino32:
-               fsopt->flags |= CEPH_MOUNT_OPT_INO32;
-               break;
-       case Opt_noino32:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_INO32;
+               if (!result.negated)
+                       fsopt->flags |= CEPH_MOUNT_OPT_INO32;
+               else
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_INO32;
                break;
+
        case Opt_fscache:
 #ifdef CONFIG_CEPH_FSCACHE
-               fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE;
                kfree(fsopt->fscache_uniq);
                fsopt->fscache_uniq = NULL;
+               if (result.negated) {
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE;
+               } else {
+                       fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE;
+                       fsopt->fscache_uniq = param->string;
+                       param->string = NULL;
+               }
                break;
 #else
-               pr_err("fscache support is disabled\n");
-               return -EINVAL;
+               return invalf(fc, "ceph: fscache support is disabled");
 #endif
-       case Opt_nofscache:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE;
-               kfree(fsopt->fscache_uniq);
-               fsopt->fscache_uniq = NULL;
-               break;
        case Opt_poolperm:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_NOPOOLPERM;
-               break;
-       case Opt_nopoolperm:
-               fsopt->flags |= CEPH_MOUNT_OPT_NOPOOLPERM;
+               if (!result.negated)
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_NOPOOLPERM;
+               else
+                       fsopt->flags |= CEPH_MOUNT_OPT_NOPOOLPERM;
                break;
        case Opt_require_active_mds:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_MOUNTWAIT;
-               break;
-       case Opt_norequire_active_mds:
-               fsopt->flags |= CEPH_MOUNT_OPT_MOUNTWAIT;
+               if (!result.negated)
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_MOUNTWAIT;
+               else
+                       fsopt->flags |= CEPH_MOUNT_OPT_MOUNTWAIT;
                break;
        case Opt_quotadf:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_NOQUOTADF;
-               break;
-       case Opt_noquotadf:
-               fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF;
+               if (!result.negated)
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_NOQUOTADF;
+               else
+                       fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF;
                break;
        case Opt_copyfrom:
-               fsopt->flags &= ~CEPH_MOUNT_OPT_NOCOPYFROM;
-               break;
-       case Opt_nocopyfrom:
-               fsopt->flags |= CEPH_MOUNT_OPT_NOCOPYFROM;
+               if (!result.negated)
+                       fsopt->flags &= ~CEPH_MOUNT_OPT_NOCOPYFROM;
+               else
+                       fsopt->flags |= CEPH_MOUNT_OPT_NOCOPYFROM;
                break;
-#ifdef CONFIG_CEPH_FS_POSIX_ACL
        case Opt_acl:
-               fsopt->sb_flags |= SB_POSIXACL;
-               break;
+               if (!result.negated) {
+#ifdef CONFIG_CEPH_FS_POSIX_ACL
+                       fc->sb_flags |= SB_POSIXACL;
+#else
+                       return invalf(fc, "ceph: POSIX ACL support is disabled");
 #endif
-       case Opt_noacl:
-               fsopt->sb_flags &= ~SB_POSIXACL;
+               } else {
+                       fc->sb_flags &= ~SB_POSIXACL;
+               }
                break;
        default:
-               BUG_ON(token);
+               BUG();
        }
        return 0;
+
+out_of_range:
+       return invalf(fc, "ceph: %s out of range", param->key);
 }
 
 static void destroy_mount_options(struct ceph_mount_options *args)
 {
        dout("destroy_mount_options %p\n", args);
+       if (!args)
+               return;
+
        kfree(args->snapdir_name);
        kfree(args->mds_namespace);
        kfree(args->server_path);
@@ -459,91 +490,6 @@ static int compare_mount_options(struct ceph_mount_options *new_fsopt,
        return ceph_compare_options(new_opt, fsc->client);
 }
 
-static int parse_mount_options(struct ceph_mount_options **pfsopt,
-                              struct ceph_options **popt,
-                              int flags, char *options,
-                              const char *dev_name)
-{
-       struct ceph_mount_options *fsopt;
-       const char *dev_name_end;
-       int err;
-
-       if (!dev_name || !*dev_name)
-               return -EINVAL;
-
-       fsopt = kzalloc(sizeof(*fsopt), GFP_KERNEL);
-       if (!fsopt)
-               return -ENOMEM;
-
-       dout("parse_mount_options %p, dev_name '%s'\n", fsopt, dev_name);
-
-       fsopt->sb_flags = flags;
-       fsopt->flags = CEPH_MOUNT_OPT_DEFAULT;
-
-       fsopt->wsize = CEPH_MAX_WRITE_SIZE;
-       fsopt->rsize = CEPH_MAX_READ_SIZE;
-       fsopt->rasize = CEPH_RASIZE_DEFAULT;
-       fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
-       if (!fsopt->snapdir_name) {
-               err = -ENOMEM;
-               goto out;
-       }
-
-       fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
-       fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
-       fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT;
-       fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
-       fsopt->congestion_kb = default_congestion_kb();
-
-       /*
-        * Distinguish the server list from the path in "dev_name".
-        * Internally we do not include the leading '/' in the path.
-        *
-        * "dev_name" will look like:
-        *     <server_spec>[,<server_spec>...]:[<path>]
-        * where
-        *     <server_spec> is <ip>[:<port>]
-        *     <path> is optional, but if present must begin with '/'
-        */
-       dev_name_end = strchr(dev_name, '/');
-       if (dev_name_end) {
-               if (strlen(dev_name_end) > 1) {
-                       fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
-                       if (!fsopt->server_path) {
-                               err = -ENOMEM;
-                               goto out;
-                       }
-               }
-       } else {
-               dev_name_end = dev_name + strlen(dev_name);
-       }
-       err = -EINVAL;
-       dev_name_end--;         /* back up to ':' separator */
-       if (dev_name_end < dev_name || *dev_name_end != ':') {
-               pr_err("device name is missing path (no : separator in %s)\n",
-                               dev_name);
-               goto out;
-       }
-       dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
-       if (fsopt->server_path)
-               dout("server path '%s'\n", fsopt->server_path);
-
-       *popt = ceph_parse_options(options, dev_name, dev_name_end,
-                                parse_fsopt_token, (void *)fsopt);
-       if (IS_ERR(*popt)) {
-               err = PTR_ERR(*popt);
-               goto out;
-       }
-
-       /* success */
-       *pfsopt = fsopt;
-       return 0;
-
-out:
-       destroy_mount_options(fsopt);
-       return err;
-}
-
 /**
  * ceph_show_options - Show mount options in /proc/mounts
  * @m: seq_file to write to
@@ -587,7 +533,7 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
                seq_puts(m, ",noquotadf");
 
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
-       if (fsopt->sb_flags & SB_POSIXACL)
+       if (root->d_sb->s_flags & SB_POSIXACL)
                seq_puts(m, ",acl");
        else
                seq_puts(m, ",noacl");
@@ -603,25 +549,25 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
                seq_show_option(m, "recover_session", "clean");
 
        if (fsopt->wsize != CEPH_MAX_WRITE_SIZE)
-               seq_printf(m, ",wsize=%d", fsopt->wsize);
+               seq_printf(m, ",wsize=%u", fsopt->wsize);
        if (fsopt->rsize != CEPH_MAX_READ_SIZE)
-               seq_printf(m, ",rsize=%d", fsopt->rsize);
+               seq_printf(m, ",rsize=%u", fsopt->rsize);
        if (fsopt->rasize != CEPH_RASIZE_DEFAULT)
-               seq_printf(m, ",rasize=%d", fsopt->rasize);
+               seq_printf(m, ",rasize=%u", fsopt->rasize);
        if (fsopt->congestion_kb != default_congestion_kb())
-               seq_printf(m, ",write_congestion_kb=%d", fsopt->congestion_kb);
+               seq_printf(m, ",write_congestion_kb=%u", fsopt->congestion_kb);
        if (fsopt->caps_max)
                seq_printf(m, ",caps_max=%d", fsopt->caps_max);
        if (fsopt->caps_wanted_delay_min != CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT)
-               seq_printf(m, ",caps_wanted_delay_min=%d",
+               seq_printf(m, ",caps_wanted_delay_min=%u",
                         fsopt->caps_wanted_delay_min);
        if (fsopt->caps_wanted_delay_max != CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT)
-               seq_printf(m, ",caps_wanted_delay_max=%d",
+               seq_printf(m, ",caps_wanted_delay_max=%u",
                           fsopt->caps_wanted_delay_max);
        if (fsopt->max_readdir != CEPH_MAX_READDIR_DEFAULT)
-               seq_printf(m, ",readdir_max_entries=%d", fsopt->max_readdir);
+               seq_printf(m, ",readdir_max_entries=%u", fsopt->max_readdir);
        if (fsopt->max_readdir_bytes != CEPH_MAX_READDIR_BYTES_DEFAULT)
-               seq_printf(m, ",readdir_max_bytes=%d", fsopt->max_readdir_bytes);
+               seq_printf(m, ",readdir_max_bytes=%u", fsopt->max_readdir_bytes);
        if (strcmp(fsopt->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT))
                seq_show_option(m, "snapdirname", fsopt->snapdir_name);
 
@@ -860,12 +806,6 @@ static void ceph_umount_begin(struct super_block *sb)
        fsc->filp_gen++; // invalidate open files
 }
 
-static int ceph_remount(struct super_block *sb, int *flags, char *data)
-{
-       sync_filesystem(sb);
-       return 0;
-}
-
 static const struct super_operations ceph_super_ops = {
        .alloc_inode    = ceph_alloc_inode,
        .free_inode     = ceph_free_inode,
@@ -874,7 +814,6 @@ static const struct super_operations ceph_super_ops = {
        .evict_inode    = ceph_evict_inode,
        .sync_fs        = ceph_sync_fs,
        .put_super      = ceph_put_super,
-       .remount_fs     = ceph_remount,
        .show_options   = ceph_show_options,
        .statfs         = ceph_statfs,
        .umount_begin   = ceph_umount_begin,
@@ -935,7 +874,8 @@ out:
 /*
  * mount: join the ceph cluster, and open root directory.
  */
-static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
+static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
+                                     struct fs_context *fc)
 {
        int err;
        unsigned long started = jiffies;  /* note the start time */
@@ -952,7 +892,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
 
                /* setup fscache */
                if (fsc->mount_options->flags & CEPH_MOUNT_OPT_FSCACHE) {
-                       err = ceph_fscache_register_fs(fsc);
+                       err = ceph_fscache_register_fs(fsc, fc);
                        if (err < 0)
                                goto out;
                }
@@ -987,18 +927,16 @@ out:
        return ERR_PTR(err);
 }
 
-static int ceph_set_super(struct super_block *s, void *data)
+static int ceph_set_super(struct super_block *s, struct fs_context *fc)
 {
-       struct ceph_fs_client *fsc = data;
+       struct ceph_fs_client *fsc = s->s_fs_info;
        int ret;
 
-       dout("set_super %p data %p\n", s, data);
+       dout("set_super %p\n", s);
 
-       s->s_flags = fsc->mount_options->sb_flags;
        s->s_maxbytes = MAX_LFS_FILESIZE;
 
        s->s_xattr = ceph_xattr_handlers;
-       s->s_fs_info = fsc;
        fsc->sb = s;
        fsc->max_file_size = 1ULL << 40; /* temp value until we get mdsmap */
 
@@ -1010,24 +948,18 @@ static int ceph_set_super(struct super_block *s, void *data)
        s->s_time_min = 0;
        s->s_time_max = U32_MAX;
 
-       ret = set_anon_super(s, NULL);  /* what is that second arg for? */
+       ret = set_anon_super_fc(s, fc);
        if (ret != 0)
-               goto fail;
-
-       return ret;
-
-fail:
-       s->s_fs_info = NULL;
-       fsc->sb = NULL;
+               fsc->sb = NULL;
        return ret;
 }
 
 /*
  * share superblock if same fs AND options
  */
-static int ceph_compare_super(struct super_block *sb, void *data)
+static int ceph_compare_super(struct super_block *sb, struct fs_context *fc)
 {
-       struct ceph_fs_client *new = data;
+       struct ceph_fs_client *new = fc->s_fs_info;
        struct ceph_mount_options *fsopt = new->mount_options;
        struct ceph_options *opt = new->client->options;
        struct ceph_fs_client *other = ceph_sb_to_client(sb);
@@ -1043,7 +975,7 @@ static int ceph_compare_super(struct super_block *sb, void *data)
                dout("fsid doesn't match\n");
                return 0;
        }
-       if (fsopt->sb_flags != other->mount_options->sb_flags) {
+       if (fc->sb_flags != (sb->s_flags & ~SB_BORN)) {
                dout("flags differ\n");
                return 0;
        }
@@ -1073,46 +1005,46 @@ static int ceph_setup_bdi(struct super_block *sb, struct ceph_fs_client *fsc)
        return 0;
 }
 
-static struct dentry *ceph_mount(struct file_system_type *fs_type,
-                      int flags, const char *dev_name, void *data)
+static int ceph_get_tree(struct fs_context *fc)
 {
+       struct ceph_parse_opts_ctx *pctx = fc->fs_private;
        struct super_block *sb;
        struct ceph_fs_client *fsc;
        struct dentry *res;
+       int (*compare_super)(struct super_block *, struct fs_context *) =
+               ceph_compare_super;
        int err;
-       int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
-       struct ceph_mount_options *fsopt = NULL;
-       struct ceph_options *opt = NULL;
 
-       dout("ceph_mount\n");
+       dout("ceph_get_tree\n");
+
+       if (!fc->source)
+               return invalf(fc, "ceph: No source");
 
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
-       flags |= SB_POSIXACL;
+       fc->sb_flags |= SB_POSIXACL;
 #endif
-       err = parse_mount_options(&fsopt, &opt, flags, data, dev_name);
-       if (err < 0) {
-               res = ERR_PTR(err);
-               goto out_final;
-       }
 
        /* create client (which we may/may not use) */
-       fsc = create_fs_client(fsopt, opt);
+       fsc = create_fs_client(pctx->opts, pctx->copts);
+       pctx->opts = NULL;
+       pctx->copts = NULL;
        if (IS_ERR(fsc)) {
-               res = ERR_CAST(fsc);
+               err = PTR_ERR(fsc);
                goto out_final;
        }
 
        err = ceph_mdsc_init(fsc);
-       if (err < 0) {
-               res = ERR_PTR(err);
+       if (err < 0)
                goto out;
-       }
 
        if (ceph_test_opt(fsc->client, NOSHARE))
                compare_super = NULL;
-       sb = sget(fs_type, compare_super, ceph_set_super, flags, fsc);
+
+       fc->s_fs_info = fsc;
+       sb = sget_fc(fc, compare_super, ceph_set_super);
+       fc->s_fs_info = NULL;
        if (IS_ERR(sb)) {
-               res = ERR_CAST(sb);
+               err = PTR_ERR(sb);
                goto out;
        }
 
@@ -1123,18 +1055,19 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type,
        } else {
                dout("get_sb using new client %p\n", fsc);
                err = ceph_setup_bdi(sb, fsc);
-               if (err < 0) {
-                       res = ERR_PTR(err);
+               if (err < 0)
                        goto out_splat;
-               }
        }
 
-       res = ceph_real_mount(fsc);
-       if (IS_ERR(res))
+       res = ceph_real_mount(fsc, fc);
+       if (IS_ERR(res)) {
+               err = PTR_ERR(res);
                goto out_splat;
+       }
        dout("root %p inode %p ino %llx.%llx\n", res,
             d_inode(res), ceph_vinop(d_inode(res)));
-       return res;
+       fc->root = fsc->sb->s_root;
+       return 0;
 
 out_splat:
        ceph_mdsc_close_sessions(fsc->mdsc);
@@ -1144,8 +1077,79 @@ out_splat:
 out:
        destroy_fs_client(fsc);
 out_final:
-       dout("ceph_mount fail %ld\n", PTR_ERR(res));
-       return res;
+       dout("ceph_get_tree fail %d\n", err);
+       return err;
+}
+
+static void ceph_free_fc(struct fs_context *fc)
+{
+       struct ceph_parse_opts_ctx *pctx = fc->fs_private;
+
+       if (pctx) {
+               destroy_mount_options(pctx->opts);
+               ceph_destroy_options(pctx->copts);
+               kfree(pctx);
+       }
+}
+
+static int ceph_reconfigure_fc(struct fs_context *fc)
+{
+       sync_filesystem(fc->root->d_sb);
+       return 0;
+}
+
+static const struct fs_context_operations ceph_context_ops = {
+       .free           = ceph_free_fc,
+       .parse_param    = ceph_parse_mount_param,
+       .get_tree       = ceph_get_tree,
+       .reconfigure    = ceph_reconfigure_fc,
+};
+
+/*
+ * Set up the filesystem mount context.
+ */
+static int ceph_init_fs_context(struct fs_context *fc)
+{
+       struct ceph_parse_opts_ctx *pctx;
+       struct ceph_mount_options *fsopt;
+
+       pctx = kzalloc(sizeof(*pctx), GFP_KERNEL);
+       if (!pctx)
+               return -ENOMEM;
+
+       pctx->copts = ceph_alloc_options();
+       if (!pctx->copts)
+               goto nomem;
+
+       pctx->opts = kzalloc(sizeof(*pctx->opts), GFP_KERNEL);
+       if (!pctx->opts)
+               goto nomem;
+
+       fsopt = pctx->opts;
+       fsopt->flags = CEPH_MOUNT_OPT_DEFAULT;
+
+       fsopt->wsize = CEPH_MAX_WRITE_SIZE;
+       fsopt->rsize = CEPH_MAX_READ_SIZE;
+       fsopt->rasize = CEPH_RASIZE_DEFAULT;
+       fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
+       if (!fsopt->snapdir_name)
+               goto nomem;
+
+       fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
+       fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
+       fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT;
+       fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
+       fsopt->congestion_kb = default_congestion_kb();
+
+       fc->fs_private = pctx;
+       fc->ops = &ceph_context_ops;
+       return 0;
+
+nomem:
+       destroy_mount_options(pctx->opts);
+       ceph_destroy_options(pctx->copts);
+       kfree(pctx);
+       return -ENOMEM;
 }
 
 static void ceph_kill_sb(struct super_block *s)
@@ -1172,7 +1176,7 @@ static void ceph_kill_sb(struct super_block *s)
 static struct file_system_type ceph_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ceph",
-       .mount          = ceph_mount,
+       .init_fs_context = ceph_init_fs_context,
        .kill_sb        = ceph_kill_sb,
        .fs_flags       = FS_RENAME_DOES_D_MOVE,
 };
index f98d924..3bf1a01 100644 (file)
 #define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT     60  /* cap release delay */
 
 struct ceph_mount_options {
-       int flags;
-       int sb_flags;
-
-       int wsize;            /* max write size */
-       int rsize;            /* max read size */
-       int rasize;           /* max readahead */
-       int congestion_kb;    /* max writeback in flight */
-       int caps_wanted_delay_min, caps_wanted_delay_max;
+       unsigned int flags;
+
+       unsigned int wsize;            /* max write size */
+       unsigned int rsize;            /* max read size */
+       unsigned int rasize;           /* max readahead */
+       unsigned int congestion_kb;    /* max writeback in flight */
+       unsigned int caps_wanted_delay_min, caps_wanted_delay_max;
        int caps_max;
-       int max_readdir;       /* max readdir result (entires) */
-       int max_readdir_bytes; /* max readdir result (bytes) */
+       unsigned int max_readdir;       /* max readdir result (entries) */
+       unsigned int max_readdir_bytes; /* max readdir result (bytes) */
 
        /*
         * everything above this point can be memcmp'd; everything below
@@ -407,22 +406,26 @@ struct ceph_inode_info {
        struct inode vfs_inode; /* at end */
 };
 
-static inline struct ceph_inode_info *ceph_inode(struct inode *inode)
+static inline struct ceph_inode_info *
+ceph_inode(const struct inode *inode)
 {
        return container_of(inode, struct ceph_inode_info, vfs_inode);
 }
 
-static inline struct ceph_fs_client *ceph_inode_to_client(struct inode *inode)
+static inline struct ceph_fs_client *
+ceph_inode_to_client(const struct inode *inode)
 {
        return (struct ceph_fs_client *)inode->i_sb->s_fs_info;
 }
 
-static inline struct ceph_fs_client *ceph_sb_to_client(struct super_block *sb)
+static inline struct ceph_fs_client *
+ceph_sb_to_client(const struct super_block *sb)
 {
        return (struct ceph_fs_client *)sb->s_fs_info;
 }
 
-static inline struct ceph_vino ceph_vino(struct inode *inode)
+static inline struct ceph_vino
+ceph_vino(const struct inode *inode)
 {
        return ceph_inode(inode)->i_vino;
 }
index 06ffe52..96ae72b 100644 (file)
@@ -802,6 +802,31 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
        return;
 }
 
+/*
+ * Fill in the special SID based on the mode. See
+ * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
+ */
+unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
+{
+       int i;
+       unsigned int ace_size = 28;
+
+       pntace->type = ACCESS_DENIED_ACE_TYPE;
+       pntace->flags = 0x0;
+       pntace->access_req = 0;
+       pntace->sid.num_subauth = 3;
+       pntace->sid.revision = 1;
+       for (i = 0; i < NUM_AUTHS; i++)
+               pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
+
+       pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
+       pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
+       pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
+
+       /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
+       pntace->size = cpu_to_le16(ace_size);
+       return ace_size;
+}
 
 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
                        struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
@@ -815,23 +840,8 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
        if (modefromsid) {
                struct cifs_ace *pntace =
                        (struct cifs_ace *)((char *)pnndacl + size);
-               int i;
 
-               pntace->type = ACCESS_ALLOWED;
-               pntace->flags = 0x0;
-               pntace->access_req = 0;
-               pntace->sid.num_subauth = 3;
-               pntace->sid.revision = 1;
-               for (i = 0; i < NUM_AUTHS; i++)
-                       pntace->sid.authority[i] =
-                               sid_unix_NFS_mode.authority[i];
-               pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
-               pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
-               pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
-
-               /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
-               pntace->size = cpu_to_le16(28);
-               size += 28;
+               size += setup_special_mode_ACE(pntace, nmode);
                num_aces++;
        }
 
index 439b99c..21d7dee 100644 (file)
@@ -147,22 +147,22 @@ struct smb3_sd {
 } __packed;
 
 /* Meaning of 'Control' field flags */
-#define ACL_CONTROL_SR 0x0001  /* Self relative */
-#define ACL_CONTROL_RM 0x0002  /* Resource manager control bits */
-#define ACL_CONTROL_PS 0x0004  /* SACL protected from inherits */
-#define ACL_CONTROL_PD 0x0008  /* DACL protected from inherits */
-#define ACL_CONTROL_SI 0x0010  /* SACL Auto-Inherited */
-#define ACL_CONTROL_DI 0x0020  /* DACL Auto-Inherited */
-#define ACL_CONTROL_SC 0x0040  /* SACL computed through inheritance */
-#define ACL_CONTROL_DC 0x0080  /* DACL computed through inheritence */
-#define ACL_CONTROL_SS 0x0100  /* Create server ACL */
-#define ACL_CONTROL_DT 0x0200  /* DACL provided by trusteed source */
-#define ACL_CONTROL_SD 0x0400  /* SACL defaulted */
-#define ACL_CONTROL_SP 0x0800  /* SACL is present on object */
-#define ACL_CONTROL_DD 0x1000  /* DACL defaulted */
-#define ACL_CONTROL_DP 0x2000  /* DACL is present on object */
-#define ACL_CONTROL_GD 0x4000  /* Group was defaulted */
-#define ACL_CONTROL_OD 0x8000  /* User was defaulted */
+#define ACL_CONTROL_SR 0x8000  /* Self relative */
+#define ACL_CONTROL_RM 0x4000  /* Resource manager control bits */
+#define ACL_CONTROL_PS 0x2000  /* SACL protected from inherits */
+#define ACL_CONTROL_PD 0x1000  /* DACL protected from inherits */
+#define ACL_CONTROL_SI 0x0800  /* SACL Auto-Inherited */
+#define ACL_CONTROL_DI 0x0400  /* DACL Auto-Inherited */
+#define ACL_CONTROL_SC 0x0200  /* SACL computed through inheritance */
+#define ACL_CONTROL_DC 0x0100  /* DACL computed through inheritence */
+#define ACL_CONTROL_SS 0x0080  /* Create server ACL */
+#define ACL_CONTROL_DT 0x0040  /* DACL provided by trusted source */
+#define ACL_CONTROL_SD 0x0020  /* SACL defaulted */
+#define ACL_CONTROL_SP 0x0010  /* SACL is present on object */
+#define ACL_CONTROL_DD 0x0008  /* DACL defaulted */
+#define ACL_CONTROL_DP 0x0004  /* DACL is present on object */
+#define ACL_CONTROL_GD 0x0002  /* Group was defaulted */
+#define ACL_CONTROL_OD 0x0001  /* User was defaulted */
 
 /* Meaning of AclRevision flags */
 #define ACL_REVISION   0x02 /* See section 2.4.4.1 of MS-DTYP */
index 1d1051d..5492b98 100644 (file)
@@ -730,11 +730,6 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
                struct inode *dir = d_inode(dentry);
                struct dentry *child;
 
-               if (!dir) {
-                       dput(dentry);
-                       dentry = ERR_PTR(-ENOENT);
-                       break;
-               }
                if (!S_ISDIR(dir->i_mode)) {
                        dput(dentry);
                        dentry = ERR_PTR(-ENOTDIR);
@@ -751,7 +746,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
                while (*s && *s != sep)
                        s++;
 
-               child = lookup_one_len_unlocked(p, dentry, s - p);
+               child = lookup_positive_unlocked(p, dentry, s - p);
                dput(dentry);
                dentry = child;
        } while (!IS_ERR(dentry));
index d34a4ed..ce9bac7 100644 (file)
@@ -368,6 +368,9 @@ struct smb_version_operations {
        /* close a file */
        void (*close)(const unsigned int, struct cifs_tcon *,
                      struct cifs_fid *);
+       /* close a file, returning file attributes and timestamps */
+       void (*close_getattr)(const unsigned int xid, struct cifs_tcon *tcon,
+                     struct cifsFileInfo *pfile_info);
        /* send a flush request to the server */
        int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *);
        /* async read from the server */
@@ -774,6 +777,7 @@ struct TCP_Server_Info {
         */
        int nr_targets;
        bool noblockcnt; /* use non-blocking connect() */
+       bool is_channel; /* if a session channel */
 };
 
 struct cifs_credits {
@@ -1057,7 +1061,7 @@ cap_unix(struct cifs_ses *ses)
 struct cached_fid {
        bool is_valid:1;        /* Do we have a useable root fid */
        bool file_all_info_is_valid:1;
-
+       bool has_lease:1;
        struct kref refcount;
        struct cifs_fid *fid;
        struct mutex fid_mutex;
index 1ed6953..9c22940 100644 (file)
@@ -213,6 +213,7 @@ extern struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *,
                                                const struct cifs_fid *, u32 *);
 extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
                                const char *, int);
+extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode);
 
 extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
 extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
index 4f554f0..cc86a67 100644 (file)
@@ -42,6 +42,7 @@
 #include "cifsproto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
+#include "smb2proto.h"
 #include "fscache.h"
 #include "smbdirect.h"
 #ifdef CONFIG_CIFS_DFS_UPCALL
@@ -112,6 +113,8 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
 
        mutex_lock(&tcon->crfid.fid_mutex);
        tcon->crfid.is_valid = false;
+       /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
+       close_shroot_lease_locked(&tcon->crfid);
        memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
        mutex_unlock(&tcon->crfid.fid_mutex);
 
index 86d1bae..05ea0e2 100644 (file)
@@ -2712,7 +2712,11 @@ cifs_find_tcp_session(struct smb_vol *vol)
 
        spin_lock(&cifs_tcp_ses_lock);
        list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
-               if (!match_server(server, vol))
+               /*
+                * Skip ses channels since they're only handled in lower layers
+                * (e.g. cifs_send_recv).
+                */
+               if (server->is_channel || !match_server(server, vol))
                        continue;
 
                ++server->srv_count;
index f1fe9c4..043288b 100644 (file)
@@ -315,9 +315,6 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
        INIT_LIST_HEAD(&fdlocks->locks);
        fdlocks->cfile = cfile;
        cfile->llist = fdlocks;
-       cifs_down_write(&cinode->lock_sem);
-       list_add(&fdlocks->llist, &cinode->llist);
-       up_write(&cinode->lock_sem);
 
        cfile->count = 1;
        cfile->pid = current->tgid;
@@ -342,6 +339,10 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
                oplock = 0;
        }
 
+       cifs_down_write(&cinode->lock_sem);
+       list_add(&fdlocks->llist, &cinode->llist);
+       up_write(&cinode->lock_sem);
+
        spin_lock(&tcon->open_file_lock);
        if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock)
                oplock = fid->pending_open->oplock;
@@ -495,7 +496,9 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file,
                unsigned int xid;
 
                xid = get_xid();
-               if (server->ops->close)
+               if (server->ops->close_getattr)
+                       server->ops->close_getattr(xid, tcon, cifs_file);
+               else if (server->ops->close)
                        server->ops->close(xid, tcon, &cifs_file->fid);
                _free_xid(xid);
        }
index 8a76195..ca76a92 100644 (file)
@@ -163,7 +163,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
 
        spin_lock(&inode->i_lock);
        /* we do not want atime to be less than mtime, it broke some apps */
-       if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime))
+       if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime) < 0)
                inode->i_atime = fattr->cf_mtime;
        else
                inode->i_atime = fattr->cf_atime;
index fb3bdc4..f0795c8 100644 (file)
@@ -77,6 +77,8 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
        int i = 0;
        int rc = 0;
        int tries = 0;
+       struct cifs_server_iface *ifaces = NULL;
+       size_t iface_count;
 
        if (left <= 0) {
                cifs_dbg(FYI,
@@ -91,6 +93,26 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
        }
 
        /*
+        * Make a copy of the iface list at the time and use that
+        * instead so as to not hold the iface spinlock for opening
+        * channels
+        */
+       spin_lock(&ses->iface_lock);
+       iface_count = ses->iface_count;
+       if (iface_count <= 0) {
+               spin_unlock(&ses->iface_lock);
+               cifs_dbg(FYI, "no iface list available to open channels\n");
+               return 0;
+       }
+       ifaces = kmemdup(ses->iface_list, iface_count*sizeof(*ifaces),
+                        GFP_ATOMIC);
+       if (!ifaces) {
+               spin_unlock(&ses->iface_lock);
+               return 0;
+       }
+       spin_unlock(&ses->iface_lock);
+
+       /*
         * Keep connecting to same, fastest, iface for all channels as
         * long as its RSS. Try next fastest one if not RSS or channel
         * creation fails.
@@ -105,9 +127,9 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
                        break;
                }
 
-               iface = &ses->iface_list[i];
+               iface = &ifaces[i];
                if (is_ses_using_iface(ses, iface) && !iface->rss_capable) {
-                       i = (i+1) % ses->iface_count;
+                       i = (i+1) % iface_count;
                        continue;
                }
 
@@ -115,7 +137,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
                if (rc) {
                        cifs_dbg(FYI, "failed to open extra channel on iface#%d rc=%d\n",
                                 i, rc);
-                       i = (i+1) % ses->iface_count;
+                       i = (i+1) % iface_count;
                        continue;
                }
 
@@ -124,6 +146,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
                left--;
        }
 
+       kfree(ifaces);
        return ses->chan_count - old_chan_count;
 }
 
@@ -213,6 +236,9 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
                chan->server = NULL;
                goto out;
        }
+       spin_lock(&cifs_tcp_ses_lock);
+       chan->server->is_channel = true;
+       spin_unlock(&cifs_tcp_ses_lock);
 
        /*
         * We need to allocate the server crypto now as we will need
index 4121ac1..5ef5e97 100644 (file)
@@ -95,6 +95,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
                goto finished;
        }
 
+       memset(&oparms, 0, sizeof(struct cifs_open_parms));
        oparms.tcon = tcon;
        oparms.desired_access = desired_access;
        oparms.disposition = create_disposition;
@@ -313,7 +314,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
        rqst[num_rqst].rq_iov = close_iov;
        rqst[num_rqst].rq_nvec = 1;
        rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID,
-                            COMPOUND_FID);
+                            COMPOUND_FID, false);
        smb2_set_related(&rqst[num_rqst]);
        if (rc)
                goto finished;
index a7f328f..6250370 100644 (file)
@@ -616,6 +616,7 @@ smb2_close_cached_fid(struct kref *ref)
                           cfid->fid->volatile_fid);
                cfid->is_valid = false;
                cfid->file_all_info_is_valid = false;
+               cfid->has_lease = false;
        }
 }
 
@@ -626,13 +627,28 @@ void close_shroot(struct cached_fid *cfid)
        mutex_unlock(&cfid->fid_mutex);
 }
 
+void close_shroot_lease_locked(struct cached_fid *cfid)
+{
+       if (cfid->has_lease) {
+               cfid->has_lease = false;
+               kref_put(&cfid->refcount, smb2_close_cached_fid);
+       }
+}
+
+void close_shroot_lease(struct cached_fid *cfid)
+{
+       mutex_lock(&cfid->fid_mutex);
+       close_shroot_lease_locked(cfid);
+       mutex_unlock(&cfid->fid_mutex);
+}
+
 void
 smb2_cached_lease_break(struct work_struct *work)
 {
        struct cached_fid *cfid = container_of(work,
                                struct cached_fid, lease_break);
 
-       close_shroot(cfid);
+       close_shroot_lease(cfid);
 }
 
 /*
@@ -773,6 +789,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
        /* BB TBD check to see if oplock level check can be removed below */
        if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) {
                kref_get(&tcon->crfid.refcount);
+               tcon->crfid.has_lease = true;
                smb2_parse_contexts(server, o_rsp,
                                &oparms.fid->epoch,
                                oparms.fid->lease_key, &oplock, NULL);
@@ -1178,7 +1195,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
        memset(&close_iov, 0, sizeof(close_iov));
        rqst[2].rq_iov = close_iov;
        rqst[2].rq_nvec = 1;
-       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
        smb2_set_related(&rqst[2]);
 
        rc = compound_send_recv(xid, ses, flags, 3, rqst,
@@ -1332,6 +1349,45 @@ smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
        SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 }
 
+static void
+smb2_close_getattr(const unsigned int xid, struct cifs_tcon *tcon,
+                  struct cifsFileInfo *cfile)
+{
+       struct smb2_file_network_open_info file_inf;
+       struct inode *inode;
+       int rc;
+
+       rc = __SMB2_close(xid, tcon, cfile->fid.persistent_fid,
+                  cfile->fid.volatile_fid, &file_inf);
+       if (rc)
+               return;
+
+       inode = d_inode(cfile->dentry);
+
+       spin_lock(&inode->i_lock);
+       CIFS_I(inode)->time = jiffies;
+
+       /* Creation time should not need to be updated on close */
+       if (file_inf.LastWriteTime)
+               inode->i_mtime = cifs_NTtimeToUnix(file_inf.LastWriteTime);
+       if (file_inf.ChangeTime)
+               inode->i_ctime = cifs_NTtimeToUnix(file_inf.ChangeTime);
+       if (file_inf.LastAccessTime)
+               inode->i_atime = cifs_NTtimeToUnix(file_inf.LastAccessTime);
+
+       /*
+        * i_blocks is not related to (i_size / i_blksize),
+        * but instead 512 byte (2**9) size is required for
+        * calculating num blocks.
+        */
+       if (le64_to_cpu(file_inf.AllocationSize) > 4096)
+               inode->i_blocks =
+                       (512 - 1 + le64_to_cpu(file_inf.AllocationSize)) >> 9;
+
+       /* End of file and Attributes should not have to be updated on close */
+       spin_unlock(&inode->i_lock);
+}
+
 static int
 SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
                     u64 persistent_fid, u64 volatile_fid,
@@ -1512,7 +1568,7 @@ smb2_ioctl_query_info(const unsigned int xid,
        rqst[2].rq_iov = close_iov;
        rqst[2].rq_nvec = 1;
 
-       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
        if (rc)
                goto iqinf_exit;
        smb2_set_related(&rqst[2]);
@@ -2241,7 +2297,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
        rqst[2].rq_iov = close_iov;
        rqst[2].rq_nvec = 1;
 
-       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
        if (rc)
                goto qic_exit;
        smb2_set_related(&rqst[2]);
@@ -2654,7 +2710,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
        rqst[2].rq_iov = close_iov;
        rqst[2].rq_nvec = 1;
 
-       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+       rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
        if (rc)
                goto querty_exit;
 
@@ -4707,6 +4763,7 @@ struct smb_version_operations smb30_operations = {
        .open = smb2_open_file,
        .set_fid = smb2_set_fid,
        .close = smb2_close_file,
+       .close_getattr = smb2_close_getattr,
        .flush = smb2_flush_file,
        .async_readv = smb2_async_readv,
        .async_writev = smb2_async_writev,
@@ -4816,6 +4873,7 @@ struct smb_version_operations smb311_operations = {
        .open = smb2_open_file,
        .set_fid = smb2_set_fid,
        .close = smb2_close_file,
+       .close_getattr = smb2_close_getattr,
        .flush = smb2_flush_file,
        .async_readv = smb2_async_readv,
        .async_writev = smb2_async_writev,
index ed77f94..9434f6d 100644 (file)
@@ -554,7 +554,7 @@ static void
 assemble_neg_contexts(struct smb2_negotiate_req *req,
                      struct TCP_Server_Info *server, unsigned int *total_len)
 {
-       char *pneg_ctxt = (char *)req;
+       char *pneg_ctxt;
        unsigned int ctxt_len;
 
        if (*total_len > 200) {
@@ -1847,7 +1847,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
        if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
                return 0;
 
-       close_shroot(&tcon->crfid);
+       close_shroot_lease(&tcon->crfid);
 
        rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, (void **) &req,
                             &total_len);
@@ -2191,6 +2191,72 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp)
        return 0;
 }
 
+/* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */
+static struct crt_sd_ctxt *
+create_sd_buf(umode_t mode, unsigned int *len)
+{
+       struct crt_sd_ctxt *buf;
+       struct cifs_ace *pace;
+       unsigned int sdlen, acelen;
+
+       *len = roundup(sizeof(struct crt_sd_ctxt) + sizeof(struct cifs_ace), 8);
+       buf = kzalloc(*len, GFP_KERNEL);
+       if (buf == NULL)
+               return buf;
+
+       sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) +
+                sizeof(struct cifs_ace);
+
+       buf->ccontext.DataOffset = cpu_to_le16(offsetof
+                                       (struct crt_sd_ctxt, sd));
+       buf->ccontext.DataLength = cpu_to_le32(sdlen);
+       buf->ccontext.NameOffset = cpu_to_le16(offsetof
+                               (struct crt_sd_ctxt, Name));
+       buf->ccontext.NameLength = cpu_to_le16(4);
+       /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
+       buf->Name[0] = 'S';
+       buf->Name[1] = 'e';
+       buf->Name[2] = 'c';
+       buf->Name[3] = 'D';
+       buf->sd.Revision = 1;  /* Must be one see MS-DTYP 2.4.6 */
+       /*
+        * ACL is "self relative" ie ACL is stored in contiguous block of memory
+        * and "DP" ie the DACL is present
+        */
+       buf->sd.Control = cpu_to_le16(ACL_CONTROL_SR | ACL_CONTROL_DP);
+
+       /* offset owner, group and Sbz1 and SACL are all zero */
+       buf->sd.OffsetDacl = cpu_to_le32(sizeof(struct smb3_sd));
+       buf->acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
+
+       /* create one ACE to hold the mode embedded in reserved special SID */
+       pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf);
+       acelen = setup_special_mode_ACE(pace, (__u64)mode);
+       buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen);
+       buf->acl.AceCount = cpu_to_le16(1);
+       return buf;
+}
+
+static int
+add_sd_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
+{
+       struct smb2_create_req *req = iov[0].iov_base;
+       unsigned int num = *num_iovec;
+       unsigned int len = 0;
+
+       iov[num].iov_base = create_sd_buf(mode, &len);
+       if (iov[num].iov_base == NULL)
+               return -ENOMEM;
+       iov[num].iov_len = len;
+       if (!req->CreateContextsOffset)
+               req->CreateContextsOffset = cpu_to_le32(
+                               sizeof(struct smb2_create_req) +
+                               iov[num - 1].iov_len);
+       le32_add_cpu(&req->CreateContextsLength, len);
+       *num_iovec = num + 1;
+       return 0;
+}
+
 static struct crt_query_id_ctxt *
 create_query_id_buf(void)
 {
@@ -2563,7 +2629,9 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
                        return rc;
        }
 
-       if ((oparms->disposition == FILE_CREATE) &&
+       if ((oparms->disposition != FILE_OPEN) &&
+           (oparms->cifs_sb) &&
+           (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) &&
            (oparms->mode != ACL_NO_MODE)) {
                if (n_iov > 2) {
                        struct create_context *ccontext =
@@ -2572,7 +2640,8 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
                                cpu_to_le32(iov[n_iov-1].iov_len);
                }
 
-               /* rc = add_sd_context(iov, &n_iov, oparms->mode); */
+               cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode);
+               rc = add_sd_context(iov, &n_iov, oparms->mode);
                if (rc)
                        return rc;
        }
@@ -2932,7 +3001,7 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
 
 int
 SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
-               u64 persistent_fid, u64 volatile_fid)
+               u64 persistent_fid, u64 volatile_fid, bool query_attrs)
 {
        struct smb2_close_req *req;
        struct kvec *iov = rqst->rq_iov;
@@ -2945,6 +3014,10 @@ SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
 
        req->PersistentFileId = persistent_fid;
        req->VolatileFileId = volatile_fid;
+       if (query_attrs)
+               req->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
+       else
+               req->Flags = 0;
        iov[0].iov_base = (char *)req;
        iov[0].iov_len = total_len;
 
@@ -2959,8 +3032,9 @@ SMB2_close_free(struct smb_rqst *rqst)
 }
 
 int
-SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
-                u64 persistent_fid, u64 volatile_fid, int flags)
+__SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
+            u64 persistent_fid, u64 volatile_fid,
+            struct smb2_file_network_open_info *pbuf)
 {
        struct smb_rqst rqst;
        struct smb2_close_rsp *rsp = NULL;
@@ -2969,6 +3043,8 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
        struct kvec rsp_iov;
        int resp_buftype = CIFS_NO_BUFFER;
        int rc = 0;
+       int flags = 0;
+       bool query_attrs = false;
 
        cifs_dbg(FYI, "Close\n");
 
@@ -2983,8 +3059,13 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
        rqst.rq_iov = iov;
        rqst.rq_nvec = 1;
 
+       /* check if need to ask server to return timestamps in close response */
+       if (pbuf)
+               query_attrs = true;
+
        trace_smb3_close_enter(xid, persistent_fid, tcon->tid, ses->Suid);
-       rc = SMB2_close_init(tcon, &rqst, persistent_fid, volatile_fid);
+       rc = SMB2_close_init(tcon, &rqst, persistent_fid, volatile_fid,
+                            query_attrs);
        if (rc)
                goto close_exit;
 
@@ -2996,42 +3077,43 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
                trace_smb3_close_err(xid, persistent_fid, tcon->tid, ses->Suid,
                                     rc);
                goto close_exit;
-       } else
+       } else {
                trace_smb3_close_done(xid, persistent_fid, tcon->tid,
                                      ses->Suid);
+               /*
+                * Note that have to subtract 4 since struct network_open_info
+                * has a final 4 byte pad that close response does not have
+                */
+               if (pbuf)
+                       memcpy(pbuf, (char *)&rsp->CreationTime, sizeof(*pbuf) - 4);
+       }
 
        atomic_dec(&tcon->num_remote_opens);
-
-       /* BB FIXME - decode close response, update inode for caching */
-
 close_exit:
        SMB2_close_free(&rqst);
        free_rsp_buf(resp_buftype, rsp);
-       return rc;
-}
-
-int
-SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
-          u64 persistent_fid, u64 volatile_fid)
-{
-       int rc;
-       int tmp_rc;
-
-       rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0);
 
        /* retry close in a worker thread if this one is interrupted */
        if (rc == -EINTR) {
+               int tmp_rc;
+
                tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid,
                                                     volatile_fid);
                if (tmp_rc)
                        cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n",
                                 persistent_fid, tmp_rc);
        }
-
        return rc;
 }
 
 int
+SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
+               u64 persistent_fid, u64 volatile_fid)
+{
+       return __SMB2_close(xid, tcon, persistent_fid, volatile_fid, NULL);
+}
+
+int
 smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
                  struct kvec *iov, unsigned int min_buf_size)
 {
index f264e1d..7b1c379 100644 (file)
@@ -25,6 +25,7 @@
 #define _SMB2PDU_H
 
 #include <net/sock.h>
+#include <cifsacl.h>
 
 /*
  * Note that, due to trying to use names similar to the protocol specifications,
@@ -855,6 +856,15 @@ struct crt_query_id_ctxt {
        __u8    Name[8];
 } __packed;
 
+struct crt_sd_ctxt {
+       struct create_context ccontext;
+       __u8    Name[8];
+       struct smb3_sd sd;
+       struct smb3_acl acl;
+       /* Followed by at least 4 ACEs */
+} __packed;
+
+
 #define COPY_CHUNK_RES_KEY_SIZE        24
 struct resume_key_req {
        char ResumeKey[COPY_CHUNK_RES_KEY_SIZE];
@@ -1570,6 +1580,17 @@ struct smb2_file_eof_info { /* encoding of request for level 10 */
        __le64 EndOfFile; /* new end of file value */
 } __packed; /* level 20 Set */
 
+struct smb2_file_network_open_info {
+       __le64 CreationTime;
+       __le64 LastAccessTime;
+       __le64 LastWriteTime;
+       __le64 ChangeTime;
+       __le64 AllocationSize;
+       __le64 EndOfFile;
+       __le32 Attributes;
+       __le32 Reserved;
+} __packed; /* level 34 Query also similar returned in close rsp and open rsp */
+
 extern char smb2_padding[7];
 
 #endif                         /* _SMB2PDU_H */
index d21a5fc..27d29f2 100644 (file)
@@ -70,6 +70,8 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server,
 extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
                        struct cifs_fid *pfid);
 extern void close_shroot(struct cached_fid *cfid);
+extern void close_shroot_lease(struct cached_fid *cfid);
+extern void close_shroot_lease_locked(struct cached_fid *cfid);
 extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst,
                                   struct smb2_file_all_info *src);
 extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
@@ -155,12 +157,13 @@ extern int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
                        u64 persistent_fid, u64 volatile_fid, bool watch_tree,
                        u32 completion_filter);
 
+extern int __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
+                       u64 persistent_fid, u64 volatile_fid,
+                       struct smb2_file_network_open_info *pbuf);
 extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
                      u64 persistent_file_id, u64 volatile_file_id);
-extern int SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
-                           u64 persistent_fid, u64 volatile_fid, int flags);
 extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
-                     u64 persistent_file_id, u64 volatile_file_id);
+                     u64 persistent_fid, u64 volatile_fid, bool query_attrs);
 extern void SMB2_close_free(struct smb_rqst *rqst);
 extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon,
                      u64 persistent_file_id, u64 volatile_file_id);
index 040df1f..40cca35 100644 (file)
@@ -151,7 +151,7 @@ static struct key *search_fscrypt_keyring(struct key *keyring,
 }
 
 #define FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE    \
-       (CONST_STRLEN("fscrypt-") + FIELD_SIZEOF(struct super_block, s_id))
+       (CONST_STRLEN("fscrypt-") + sizeof_field(struct super_block, s_id))
 
 #define FSCRYPT_MK_DESCRIPTION_SIZE    (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1)
 
index f7931b6..b280e07 100644 (file)
@@ -319,7 +319,7 @@ static inline void __d_set_inode_and_type(struct dentry *dentry,
        flags = READ_ONCE(dentry->d_flags);
        flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU);
        flags |= type_flags;
-       WRITE_ONCE(dentry->d_flags, flags);
+       smp_store_release(&dentry->d_flags, flags);
 }
 
 static inline void __d_clear_type_and_inode(struct dentry *dentry)
@@ -903,17 +903,19 @@ struct dentry *dget_parent(struct dentry *dentry)
 {
        int gotref;
        struct dentry *ret;
+       unsigned seq;
 
        /*
         * Do optimistic parent lookup without any
         * locking.
         */
        rcu_read_lock();
+       seq = raw_seqcount_begin(&dentry->d_seq);
        ret = READ_ONCE(dentry->d_parent);
        gotref = lockref_get_not_zero(&ret->d_lockref);
        rcu_read_unlock();
        if (likely(gotref)) {
-               if (likely(ret == READ_ONCE(dentry->d_parent)))
+               if (!read_seqcount_retry(&dentry->d_seq, seq))
                        return ret;
                dput(ret);
        }
@@ -1679,7 +1681,7 @@ EXPORT_SYMBOL(d_invalidate);
  * copied and the copy passed in may be reused after this call.
  */
  
-struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
+static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
 {
        struct dentry *dentry;
        char *dname;
index 7b975db..f4d8df5 100644 (file)
@@ -299,13 +299,9 @@ struct dentry *debugfs_lookup(const char *name, struct dentry *parent)
        if (!parent)
                parent = debugfs_mount->mnt_root;
 
-       dentry = lookup_one_len_unlocked(name, parent, strlen(name));
+       dentry = lookup_positive_unlocked(name, parent, strlen(name));
        if (IS_ERR(dentry))
                return NULL;
-       if (!d_really_is_positive(dentry)) {
-               dput(dentry);
-               return NULL;
-       }
        return dentry;
 }
 EXPORT_SYMBOL_GPL(debugfs_lookup);
index a13a787..b766c3e 100644 (file)
@@ -649,6 +649,8 @@ ssize_t erofs_listxattr(struct dentry *dentry,
        struct listxattr_iter it;
 
        ret = init_inode_xattrs(d_inode(dentry));
+       if (ret == -ENOATTR)
+               return 0;
        if (ret)
                return ret;
 
index c4159bc..67a3950 100644 (file)
@@ -551,28 +551,23 @@ out_unlock:
  */
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
-static struct nested_calls poll_safewake_ncalls;
-
-static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests)
-{
-       unsigned long flags;
-       wait_queue_head_t *wqueue = (wait_queue_head_t *)cookie;
-
-       spin_lock_irqsave_nested(&wqueue->lock, flags, call_nests + 1);
-       wake_up_locked_poll(wqueue, EPOLLIN);
-       spin_unlock_irqrestore(&wqueue->lock, flags);
-
-       return 0;
-}
+static DEFINE_PER_CPU(int, wakeup_nest);
 
 static void ep_poll_safewake(wait_queue_head_t *wq)
 {
-       int this_cpu = get_cpu();
-
-       ep_call_nested(&poll_safewake_ncalls,
-                      ep_poll_wakeup_proc, NULL, wq, (void *) (long) this_cpu);
+       unsigned long flags;
+       int subclass;
 
-       put_cpu();
+       local_irq_save(flags);
+       preempt_disable();
+       subclass = __this_cpu_read(wakeup_nest);
+       spin_lock_nested(&wq->lock, subclass + 1);
+       __this_cpu_inc(wakeup_nest);
+       wake_up_locked_poll(wq, POLLIN);
+       __this_cpu_dec(wakeup_nest);
+       spin_unlock(&wq->lock);
+       local_irq_restore(flags);
+       preempt_enable();
 }
 
 #else
@@ -671,7 +666,6 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
                              void *priv, int depth, bool ep_locked)
 {
        __poll_t res;
-       int pwake = 0;
        struct epitem *epi, *nepi;
        LIST_HEAD(txlist);
 
@@ -738,26 +732,11 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
         */
        list_splice(&txlist, &ep->rdllist);
        __pm_relax(ep->ws);
-
-       if (!list_empty(&ep->rdllist)) {
-               /*
-                * Wake up (if active) both the eventpoll wait list and
-                * the ->poll() wait list (delayed after we release the lock).
-                */
-               if (waitqueue_active(&ep->wq))
-                       wake_up(&ep->wq);
-               if (waitqueue_active(&ep->poll_wait))
-                       pwake++;
-       }
        write_unlock_irq(&ep->lock);
 
        if (!ep_locked)
                mutex_unlock(&ep->mtx);
 
-       /* We have to call this outside the lock */
-       if (pwake)
-               ep_poll_safewake(&ep->poll_wait);
-
        return res;
 }
 
@@ -2370,11 +2349,6 @@ static int __init eventpoll_init(void)
         */
        ep_nested_calls_init(&poll_loop_ncalls);
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-       /* Initialize the structure used to perform safe poll wait head wake ups */
-       ep_nested_calls_init(&poll_safewake_ncalls);
-#endif
-
        /*
         * We can have many thousands of epitems, so prevent this from
         * using an extra cache line on 64-bit (and smaller) CPUs
index 92a9da1..bbce1c3 100644 (file)
@@ -25,7 +25,7 @@
  * For constructing the negative timestamp lower bound value.
  * binary: 10000000 00000000 00000000 00000000
  */
-#define LOWER_MSB_1 (-0x80000000L)
+#define LOWER_MSB_1 (-(UPPER_MSB_0) - 1L)  /* avoid overflow */
 /*
  * For constructing the negative timestamp upper bound value.
  * binary: 11111111 11111111 11111111 11111111
index 41b6438..9bc1675 100644 (file)
@@ -277,7 +277,7 @@ static long fcntl_rw_hint(struct file *file, unsigned int cmd,
                          unsigned long arg)
 {
        struct inode *inode = file_inode(file);
-       u64 *argp = (u64 __user *)arg;
+       u64 __user *argp = (u64 __user *)arg;
        enum rw_hint hint;
        u64 h;
 
index 3da91a1..2f4fcf9 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -960,7 +960,7 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
        return ksys_dup3(oldfd, newfd, 0);
 }
 
-int ksys_dup(unsigned int fildes)
+SYSCALL_DEFINE1(dup, unsigned int, fildes)
 {
        int ret = -EBADF;
        struct file *file = fget_raw(fildes);
@@ -975,11 +975,6 @@ int ksys_dup(unsigned int fildes)
        return ret;
 }
 
-SYSCALL_DEFINE1(dup, unsigned int, fildes)
-{
-       return ksys_dup(fildes);
-}
-
 int f_dupfd(unsigned int from, struct file *file, unsigned flags)
 {
        int err;
index 0635cba..eb2a585 100644 (file)
@@ -34,7 +34,7 @@ config VIRTIO_FS
        select VIRTIO
        help
          The Virtio Filesystem allows guests to mount file systems from the
-          host.
+         host.
 
          If you want to share files between guests or with the host, answer Y
-          or M.
+         or M.
index d4e6691..8e02d76 100644 (file)
@@ -1965,7 +1965,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
 
        nbuf = 0;
        rem = 0;
-       for (idx = tail; idx < head && rem < len; idx++)
+       for (idx = tail; idx != head && rem < len; idx++)
                rem += pipe->bufs[idx & mask].len;
 
        ret = -EINVAL;
index 54d638f..ee19011 100644 (file)
@@ -248,7 +248,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                kfree(forget);
                if (ret == -ENOMEM)
                        goto out;
-               if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
+               if (ret || fuse_invalid_attr(&outarg.attr) ||
+                   (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
                        goto invalid;
 
                forget_all_cached_acls(inode);
@@ -319,6 +320,12 @@ int fuse_valid_type(int m)
                S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
 }
 
+bool fuse_invalid_attr(struct fuse_attr *attr)
+{
+       return !fuse_valid_type(attr->mode) ||
+               attr->size > LLONG_MAX;
+}
+
 int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
                     struct fuse_entry_out *outarg, struct inode **inode)
 {
@@ -350,7 +357,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
        err = -EIO;
        if (!outarg->nodeid)
                goto out_put_forget;
-       if (!fuse_valid_type(outarg->attr.mode))
+       if (fuse_invalid_attr(&outarg->attr))
                goto out_put_forget;
 
        *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
@@ -475,7 +482,8 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
                goto out_free_ff;
 
        err = -EIO;
-       if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
+       if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
+           fuse_invalid_attr(&outentry.attr))
                goto out_free_ff;
 
        ff->fh = outopen.fh;
@@ -583,7 +591,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
                goto out_put_forget_req;
 
        err = -EIO;
-       if (invalid_nodeid(outarg.nodeid))
+       if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
                goto out_put_forget_req;
 
        if ((outarg.attr.mode ^ mode) & S_IFMT)
@@ -862,7 +870,8 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
 
                spin_lock(&fi->lock);
                fi->attr_version = atomic64_inc_return(&fc->attr_version);
-               inc_nlink(inode);
+               if (likely(inode->i_nlink < UINT_MAX))
+                       inc_nlink(inode);
                spin_unlock(&fi->lock);
                fuse_invalidate_attr(inode);
                fuse_update_ctime(inode);
@@ -942,7 +951,8 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
        args.out_args[0].value = &outarg;
        err = fuse_simple_request(fc, &args);
        if (!err) {
-               if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+               if (fuse_invalid_attr(&outarg.attr) ||
+                   (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
                        make_bad_inode(inode);
                        err = -EIO;
                } else {
@@ -1563,7 +1573,8 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
                goto error;
        }
 
-       if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+       if (fuse_invalid_attr(&outarg.attr) ||
+           (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
                make_bad_inode(inode);
                err = -EIO;
                goto error;
index db48a5c..a63d779 100644 (file)
@@ -713,8 +713,10 @@ static ssize_t fuse_async_req_send(struct fuse_conn *fc,
 
        ia->ap.args.end = fuse_aio_complete_req;
        err = fuse_simple_background(fc, &ia->ap.args, GFP_KERNEL);
+       if (err)
+               fuse_aio_complete_req(fc, &ia->ap.args, err);
 
-       return err ?: num_bytes;
+       return num_bytes;
 }
 
 static ssize_t fuse_send_read(struct fuse_io_args *ia, loff_t pos, size_t count,
@@ -1096,6 +1098,8 @@ static ssize_t fuse_send_write_pages(struct fuse_io_args *ia,
        ia->write.in.flags = fuse_write_flags(iocb);
 
        err = fuse_simple_request(fc, &ap->args);
+       if (!err && ia->write.out.size > count)
+               err = -EIO;
 
        offset = ap->descs[0].offset;
        count = ia->write.out.size;
index d148188..aa75e23 100644 (file)
@@ -989,6 +989,8 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc);
  */
 int fuse_valid_type(int m);
 
+bool fuse_invalid_attr(struct fuse_attr *attr);
+
 /**
  * Is current process allowed to perform filesystem operation?
  */
index 5c38b9d..6a40f75 100644 (file)
@@ -184,7 +184,7 @@ static int fuse_direntplus_link(struct file *file,
 
        if (invalid_nodeid(o->nodeid))
                return -EIO;
-       if (!fuse_valid_type(o->attr.mode))
+       if (fuse_invalid_attr(&o->attr))
                return -EIO;
 
        fc = get_fuse_conn(dir);
index a5c8604..bade747 100644 (file)
@@ -35,6 +35,7 @@ struct virtio_fs_vq {
        struct fuse_dev *fud;
        bool connected;
        long in_flight;
+       struct completion in_flight_zero; /* No inflight requests */
        char name[24];
 } ____cacheline_aligned_in_smp;
 
@@ -48,11 +49,15 @@ struct virtio_fs {
        unsigned int num_request_queues; /* number of request queues */
 };
 
-struct virtio_fs_forget {
+struct virtio_fs_forget_req {
        struct fuse_in_header ih;
        struct fuse_forget_in arg;
+};
+
+struct virtio_fs_forget {
        /* This request can be temporarily queued on virt queue */
        struct list_head list;
+       struct virtio_fs_forget_req req;
 };
 
 static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
@@ -81,6 +86,8 @@ static inline void dec_in_flight_req(struct virtio_fs_vq *fsvq)
 {
        WARN_ON(fsvq->in_flight <= 0);
        fsvq->in_flight--;
+       if (!fsvq->in_flight)
+               complete(&fsvq->in_flight_zero);
 }
 
 static void release_virtio_fs_obj(struct kref *ref)
@@ -111,22 +118,23 @@ static void virtio_fs_drain_queue(struct virtio_fs_vq *fsvq)
        WARN_ON(fsvq->in_flight < 0);
 
        /* Wait for in flight requests to finish.*/
-       while (1) {
-               spin_lock(&fsvq->lock);
-               if (!fsvq->in_flight) {
-                       spin_unlock(&fsvq->lock);
-                       break;
-               }
+       spin_lock(&fsvq->lock);
+       if (fsvq->in_flight) {
+               /* We are holding virtio_fs_mutex. There should not be any
+                * waiters waiting for completion.
+                */
+               reinit_completion(&fsvq->in_flight_zero);
+               spin_unlock(&fsvq->lock);
+               wait_for_completion(&fsvq->in_flight_zero);
+       } else {
                spin_unlock(&fsvq->lock);
-               /* TODO use completion instead of timeout */
-               usleep_range(1000, 2000);
        }
 
        flush_work(&fsvq->done_work);
        flush_delayed_work(&fsvq->dispatch_work);
 }
 
-static void virtio_fs_drain_all_queues(struct virtio_fs *fs)
+static void virtio_fs_drain_all_queues_locked(struct virtio_fs *fs)
 {
        struct virtio_fs_vq *fsvq;
        int i;
@@ -137,6 +145,19 @@ static void virtio_fs_drain_all_queues(struct virtio_fs *fs)
        }
 }
 
+static void virtio_fs_drain_all_queues(struct virtio_fs *fs)
+{
+       /* Provides mutual exclusion between ->remove and ->kill_sb
+        * paths. We don't want both of these draining queue at the
+        * same time. Current completion logic reinits completion
+        * and that means there should not be any other thread
+        * doing reinit or waiting for completion already.
+        */
+       mutex_lock(&virtio_fs_mutex);
+       virtio_fs_drain_all_queues_locked(fs);
+       mutex_unlock(&virtio_fs_mutex);
+}
+
 static void virtio_fs_start_all_queues(struct virtio_fs *fs)
 {
        struct virtio_fs_vq *fsvq;
@@ -313,17 +334,72 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work)
        }
 }
 
+/*
+ * Returns 1 if queue is full and sender should wait a bit before sending
+ * next request, 0 otherwise.
+ */
+static int send_forget_request(struct virtio_fs_vq *fsvq,
+                              struct virtio_fs_forget *forget,
+                              bool in_flight)
+{
+       struct scatterlist sg;
+       struct virtqueue *vq;
+       int ret = 0;
+       bool notify;
+       struct virtio_fs_forget_req *req = &forget->req;
+
+       spin_lock(&fsvq->lock);
+       if (!fsvq->connected) {
+               if (in_flight)
+                       dec_in_flight_req(fsvq);
+               kfree(forget);
+               goto out;
+       }
+
+       sg_init_one(&sg, req, sizeof(*req));
+       vq = fsvq->vq;
+       dev_dbg(&vq->vdev->dev, "%s\n", __func__);
+
+       ret = virtqueue_add_outbuf(vq, &sg, 1, forget, GFP_ATOMIC);
+       if (ret < 0) {
+               if (ret == -ENOMEM || ret == -ENOSPC) {
+                       pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later\n",
+                                ret);
+                       list_add_tail(&forget->list, &fsvq->queued_reqs);
+                       schedule_delayed_work(&fsvq->dispatch_work,
+                                             msecs_to_jiffies(1));
+                       if (!in_flight)
+                               inc_in_flight_req(fsvq);
+                       /* Queue is full */
+                       ret = 1;
+               } else {
+                       pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n",
+                                ret);
+                       kfree(forget);
+                       if (in_flight)
+                               dec_in_flight_req(fsvq);
+               }
+               goto out;
+       }
+
+       if (!in_flight)
+               inc_in_flight_req(fsvq);
+       notify = virtqueue_kick_prepare(vq);
+       spin_unlock(&fsvq->lock);
+
+       if (notify)
+               virtqueue_notify(vq);
+       return ret;
+out:
+       spin_unlock(&fsvq->lock);
+       return ret;
+}
+
 static void virtio_fs_hiprio_dispatch_work(struct work_struct *work)
 {
        struct virtio_fs_forget *forget;
        struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
                                                 dispatch_work.work);
-       struct virtqueue *vq = fsvq->vq;
-       struct scatterlist sg;
-       struct scatterlist *sgs[] = {&sg};
-       bool notify;
-       int ret;
-
        pr_debug("virtio-fs: worker %s called.\n", __func__);
        while (1) {
                spin_lock(&fsvq->lock);
@@ -335,43 +411,9 @@ static void virtio_fs_hiprio_dispatch_work(struct work_struct *work)
                }
 
                list_del(&forget->list);
-               if (!fsvq->connected) {
-                       dec_in_flight_req(fsvq);
-                       spin_unlock(&fsvq->lock);
-                       kfree(forget);
-                       continue;
-               }
-
-               sg_init_one(&sg, forget, sizeof(*forget));
-
-               /* Enqueue the request */
-               dev_dbg(&vq->vdev->dev, "%s\n", __func__);
-               ret = virtqueue_add_sgs(vq, sgs, 1, 0, forget, GFP_ATOMIC);
-               if (ret < 0) {
-                       if (ret == -ENOMEM || ret == -ENOSPC) {
-                               pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later\n",
-                                        ret);
-                               list_add_tail(&forget->list,
-                                               &fsvq->queued_reqs);
-                               schedule_delayed_work(&fsvq->dispatch_work,
-                                               msecs_to_jiffies(1));
-                       } else {
-                               pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n",
-                                        ret);
-                               dec_in_flight_req(fsvq);
-                               kfree(forget);
-                       }
-                       spin_unlock(&fsvq->lock);
-                       return;
-               }
-
-               notify = virtqueue_kick_prepare(vq);
                spin_unlock(&fsvq->lock);
-
-               if (notify)
-                       virtqueue_notify(vq);
-               pr_debug("virtio-fs: worker %s dispatched one forget request.\n",
-                        __func__);
+               if (send_forget_request(fsvq, forget, true))
+                       return;
        }
 }
 
@@ -556,6 +598,7 @@ static int virtio_fs_setup_vqs(struct virtio_device *vdev,
        INIT_LIST_HEAD(&fs->vqs[VQ_HIPRIO].end_reqs);
        INIT_DELAYED_WORK(&fs->vqs[VQ_HIPRIO].dispatch_work,
                        virtio_fs_hiprio_dispatch_work);
+       init_completion(&fs->vqs[VQ_HIPRIO].in_flight_zero);
        spin_lock_init(&fs->vqs[VQ_HIPRIO].lock);
 
        /* Initialize the requests virtqueues */
@@ -566,6 +609,7 @@ static int virtio_fs_setup_vqs(struct virtio_device *vdev,
                                  virtio_fs_request_dispatch_work);
                INIT_LIST_HEAD(&fs->vqs[i].queued_reqs);
                INIT_LIST_HEAD(&fs->vqs[i].end_reqs);
+               init_completion(&fs->vqs[i].in_flight_zero);
                snprintf(fs->vqs[i].name, sizeof(fs->vqs[i].name),
                         "requests.%u", i - VQ_REQUEST);
                callbacks[i] = virtio_fs_vq_done;
@@ -659,7 +703,7 @@ static void virtio_fs_remove(struct virtio_device *vdev)
        /* This device is going away. No one should get new reference */
        list_del_init(&fs->list);
        virtio_fs_stop_all_queues(fs);
-       virtio_fs_drain_all_queues(fs);
+       virtio_fs_drain_all_queues_locked(fs);
        vdev->config->reset(vdev);
        virtio_fs_cleanup_vqs(vdev, fs);
 
@@ -684,12 +728,12 @@ static int virtio_fs_restore(struct virtio_device *vdev)
 }
 #endif /* CONFIG_PM_SLEEP */
 
-const static struct virtio_device_id id_table[] = {
+static const struct virtio_device_id id_table[] = {
        { VIRTIO_ID_FS, VIRTIO_DEV_ANY_ID },
        {},
 };
 
-const static unsigned int feature_table[] = {};
+static const unsigned int feature_table[] = {};
 
 static struct virtio_driver virtio_fs_driver = {
        .driver.name            = KBUILD_MODNAME,
@@ -710,14 +754,10 @@ __releases(fiq->lock)
 {
        struct fuse_forget_link *link;
        struct virtio_fs_forget *forget;
-       struct scatterlist sg;
-       struct scatterlist *sgs[] = {&sg};
+       struct virtio_fs_forget_req *req;
        struct virtio_fs *fs;
-       struct virtqueue *vq;
        struct virtio_fs_vq *fsvq;
-       bool notify;
        u64 unique;
-       int ret;
 
        link = fuse_dequeue_forget(fiq, 1, NULL);
        unique = fuse_get_unique(fiq);
@@ -728,57 +768,19 @@ __releases(fiq->lock)
 
        /* Allocate a buffer for the request */
        forget = kmalloc(sizeof(*forget), GFP_NOFS | __GFP_NOFAIL);
+       req = &forget->req;
 
-       forget->ih = (struct fuse_in_header){
+       req->ih = (struct fuse_in_header){
                .opcode = FUSE_FORGET,
                .nodeid = link->forget_one.nodeid,
                .unique = unique,
-               .len = sizeof(*forget),
+               .len = sizeof(*req),
        };
-       forget->arg = (struct fuse_forget_in){
+       req->arg = (struct fuse_forget_in){
                .nlookup = link->forget_one.nlookup,
        };
 
-       sg_init_one(&sg, forget, sizeof(*forget));
-
-       /* Enqueue the request */
-       spin_lock(&fsvq->lock);
-
-       if (!fsvq->connected) {
-               kfree(forget);
-               spin_unlock(&fsvq->lock);
-               goto out;
-       }
-
-       vq = fsvq->vq;
-       dev_dbg(&vq->vdev->dev, "%s\n", __func__);
-
-       ret = virtqueue_add_sgs(vq, sgs, 1, 0, forget, GFP_ATOMIC);
-       if (ret < 0) {
-               if (ret == -ENOMEM || ret == -ENOSPC) {
-                       pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later.\n",
-                                ret);
-                       list_add_tail(&forget->list, &fsvq->queued_reqs);
-                       schedule_delayed_work(&fsvq->dispatch_work,
-                                       msecs_to_jiffies(1));
-                       inc_in_flight_req(fsvq);
-               } else {
-                       pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n",
-                                ret);
-                       kfree(forget);
-               }
-               spin_unlock(&fsvq->lock);
-               goto out;
-       }
-
-       inc_in_flight_req(fsvq);
-       notify = virtqueue_kick_prepare(vq);
-
-       spin_unlock(&fsvq->lock);
-
-       if (notify)
-               virtqueue_notify(vq);
-out:
+       send_forget_request(fsvq, forget, false);
        kfree(link);
 }
 
@@ -1026,7 +1028,7 @@ __releases(fiq->lock)
        }
 }
 
-const static struct fuse_iqueue_ops virtio_fs_fiq_ops = {
+static const struct fuse_iqueue_ops virtio_fs_fiq_ops = {
        .wake_forget_and_unlock         = virtio_fs_wake_forget_and_unlock,
        .wake_interrupt_and_unlock      = virtio_fs_wake_interrupt_and_unlock,
        .wake_pending_and_unlock        = virtio_fs_wake_pending_and_unlock,
index b9fe975..9c6df72 100644 (file)
@@ -133,7 +133,7 @@ static int gfs2_write_full_page(struct page *page, get_block_t *get_block,
         * the  page size, the remaining memory is zeroed when mapped, and
         * writes to that region are not written out to the file."
         */
-       offset = i_size & (PAGE_SIZE-1);
+       offset = i_size & (PAGE_SIZE - 1);
        if (page->index == end_index && offset)
                zero_user_segment(page, offset, PAGE_SIZE);
 
@@ -497,7 +497,7 @@ static int __gfs2_readpage(void *file, struct page *page)
                error = mpage_readpage(page, gfs2_block_map);
        }
 
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)))
+       if (unlikely(gfs2_withdrawn(sdp)))
                return -EIO;
 
        return error;
@@ -614,7 +614,7 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
        gfs2_glock_dq(&gh);
 out_uninit:
        gfs2_holder_uninit(&gh);
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)))
+       if (unlikely(gfs2_withdrawn(sdp)))
                ret = -EIO;
        return ret;
 }
index 5161032..08f6fbb 100644 (file)
@@ -2441,8 +2441,16 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
        struct inode *inode = file_inode(file);
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
+       unsigned int blocksize = i_blocksize(inode);
+       loff_t start, end;
        int error;
 
+       start = round_down(offset, blocksize);
+       end = round_up(offset + length, blocksize) - 1;
+       error = filemap_write_and_wait_range(inode->i_mapping, start, end);
+       if (error)
+               return error;
+
        if (gfs2_is_jdata(ip))
                error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
                                         GFS2_JTRUNC_REVOKES);
@@ -2456,9 +2464,8 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
                if (error)
                        goto out;
        } else {
-               unsigned int start_off, end_len, blocksize;
+               unsigned int start_off, end_len;
 
-               blocksize = i_blocksize(inode);
                start_off = offset & (blocksize - 1);
                end_len = (offset + length) & (blocksize - 1);
                if (start_off) {
index d07a295..9d58295 100644 (file)
@@ -407,27 +407,28 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size)
 /**
  * gfs2_allocate_page_backing - Allocate blocks for a write fault
  * @page: The (locked) page to allocate backing for
+ * @length: Size of the allocation
  *
  * We try to allocate all the blocks required for the page in one go.  This
  * might fail for various reasons, so we keep trying until all the blocks to
  * back this page are allocated.  If some of the blocks are already allocated,
  * that is ok too.
  */
-static int gfs2_allocate_page_backing(struct page *page)
+static int gfs2_allocate_page_backing(struct page *page, unsigned int length)
 {
        u64 pos = page_offset(page);
-       u64 size = PAGE_SIZE;
 
        do {
                struct iomap iomap = { };
 
-               if (gfs2_iomap_get_alloc(page->mapping->host, pos, 1, &iomap))
+               if (gfs2_iomap_get_alloc(page->mapping->host, pos, length, &iomap))
                        return -EIO;
 
-               iomap.length = min(iomap.length, size);
-               size -= iomap.length;
+               if (length < iomap.length)
+                       iomap.length = length;
+               length -= iomap.length;
                pos += iomap.length;
-       } while (size > 0);
+       } while (length > 0);
 
        return 0;
 }
@@ -448,10 +449,10 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_alloc_parms ap = { .aflags = 0, };
-       unsigned long last_index;
-       u64 pos = page_offset(page);
+       u64 offset = page_offset(page);
        unsigned int data_blocks, ind_blocks, rblocks;
        struct gfs2_holder gh;
+       unsigned int length;
        loff_t size;
        int ret;
 
@@ -461,20 +462,39 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
        if (ret)
                goto out;
 
-       gfs2_size_hint(vmf->vma->vm_file, pos, PAGE_SIZE);
-
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
        ret = gfs2_glock_nq(&gh);
        if (ret)
                goto out_uninit;
 
+       /* Check page index against inode size */
+       size = i_size_read(inode);
+       if (offset >= size) {
+               ret = -EINVAL;
+               goto out_unlock;
+       }
+
        /* Update file times before taking page lock */
        file_update_time(vmf->vma->vm_file);
 
+       /* page is wholly or partially inside EOF */
+       if (offset > size - PAGE_SIZE)
+               length = offset_in_page(size);
+       else
+               length = PAGE_SIZE;
+
+       gfs2_size_hint(vmf->vma->vm_file, offset, length);
+
        set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
        set_bit(GIF_SW_PAGED, &ip->i_flags);
 
-       if (!gfs2_write_alloc_required(ip, pos, PAGE_SIZE)) {
+       /*
+        * iomap_writepage / iomap_writepages currently don't support inline
+        * files, so always unstuff here.
+        */
+
+       if (!gfs2_is_stuffed(ip) &&
+           !gfs2_write_alloc_required(ip, offset, length)) {
                lock_page(page);
                if (!PageUptodate(page) || page->mapping != inode->i_mapping) {
                        ret = -EAGAIN;
@@ -487,7 +507,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
        if (ret)
                goto out_unlock;
 
-       gfs2_write_calc_reserv(ip, PAGE_SIZE, &data_blocks, &ind_blocks);
+       gfs2_write_calc_reserv(ip, length, &data_blocks, &ind_blocks);
        ap.target = data_blocks + ind_blocks;
        ret = gfs2_quota_lock_check(ip, &ap);
        if (ret)
@@ -508,13 +528,6 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
                goto out_trans_fail;
 
        lock_page(page);
-       ret = -EINVAL;
-       size = i_size_read(inode);
-       last_index = (size - 1) >> PAGE_SHIFT;
-       /* Check page index against inode size */
-       if (size == 0 || (page->index > last_index))
-               goto out_trans_end;
-
        ret = -EAGAIN;
        /* If truncated, we must retry the operation, we may have raced
         * with the glock demotion code.
@@ -527,7 +540,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
        if (gfs2_is_stuffed(ip))
                ret = gfs2_unstuff_dinode(ip, page);
        if (ret == 0)
-               ret = gfs2_allocate_page_backing(page);
+               ret = gfs2_allocate_page_backing(page, length);
 
 out_trans_end:
        if (ret)
@@ -961,6 +974,7 @@ out:
        brelse(dibh);
        return error;
 }
+
 /**
  * calc_max_reserv() - Reverse of write_calc_reserv. Given a number of
  *                     blocks, determine how many bytes can be written.
@@ -1208,7 +1222,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
                cmd = F_SETLK;
                fl->fl_type = F_UNLCK;
        }
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) {
+       if (unlikely(gfs2_withdrawn(sdp))) {
                if (fl->fl_type == F_UNLCK)
                        locks_lock_file_wait(file, fl);
                return -EIO;
index 0290a22..b7123de 100644 (file)
@@ -549,7 +549,7 @@ __acquires(&gl->gl_lockref.lock)
        unsigned int lck_flags = (unsigned int)(gh ? gh->gh_flags : 0);
        int ret;
 
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) &&
+       if (unlikely(gfs2_withdrawn(sdp)) &&
            target != LM_ST_UNLOCKED)
                return;
        lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
@@ -558,7 +558,14 @@ __acquires(&gl->gl_lockref.lock)
        GLOCK_BUG_ON(gl, gl->gl_state == gl->gl_target);
        if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) &&
            glops->go_inval) {
-               set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags);
+               /*
+                * If another process is already doing the invalidate, let that
+                * finish first.  The glock state machine will get back to this
+                * holder again later.
+                */
+               if (test_and_set_bit(GLF_INVALIDATE_IN_PROGRESS,
+                                    &gl->gl_flags))
+                       return;
                do_error(gl, 0); /* Fail queued try locks */
        }
        gl->gl_req = target;
@@ -586,8 +593,7 @@ __acquires(&gl->gl_lockref.lock)
                }
                else if (ret) {
                        fs_err(sdp, "lm_lock ret %d\n", ret);
-                       GLOCK_BUG_ON(gl, !test_bit(SDF_WITHDRAWN,
-                                                  &sdp->sd_flags));
+                       GLOCK_BUG_ON(gl, !gfs2_withdrawn(sdp));
                }
        } else { /* lock_nolock */
                finish_xmote(gl, target);
@@ -1191,7 +1197,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
        struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
        int error = 0;
 
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)))
+       if (unlikely(gfs2_withdrawn(sdp)))
                return -EIO;
 
        if (test_bit(GLF_LRU, &gl->gl_flags))
index ff21369..4ede1f1 100644 (file)
@@ -350,7 +350,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
                ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major),
                                           be32_to_cpu(str->di_minor));
                break;
-       };
+       }
 
        i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid));
        i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid));
@@ -540,7 +540,7 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh)
                        gfs2_consist(sdp);
 
                /*  Initialize some head of the log stuff  */
-               if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) {
+               if (!gfs2_withdrawn(sdp)) {
                        sdp->sd_log_sequence = head.lh_sequence + 1;
                        gfs2_log_pointers_init(sdp, head.lh_blkno);
                }
index e1e18fb..dafef10 100644 (file)
@@ -656,7 +656,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        inode->i_rdev = dev;
        inode->i_size = size;
        inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
-       gfs2_set_inode_blocks(inode, 1);
        munge_mode_uid_gid(dip, inode);
        check_and_update_goal(dip);
        ip->i_goal = dip->i_goal;
@@ -712,7 +711,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 
        error = gfs2_trans_begin(sdp, blocks, 0);
        if (error)
-               goto fail_gunlock2;
+               goto fail_free_inode;
 
        if (blocks > 1) {
                ip->i_eattr = ip->i_no_addr + 1;
@@ -723,7 +722,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 
        error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
        if (error)
-               goto fail_gunlock2;
+               goto fail_free_inode;
 
        BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags));
 
@@ -732,7 +731,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
                goto fail_gunlock2;
 
        glock_set_object(ip->i_iopen_gh.gh_gl, ip);
-       gfs2_glock_put(io_gl);
        gfs2_set_iop(inode);
        insert_inode_hash(inode);
 
@@ -765,6 +763,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 
        mark_inode_dirty(inode);
        d_instantiate(dentry, inode);
+       /* After instantiate, errors should result in evict which will destroy
+        * both inode and iopen glocks properly. */
        if (file) {
                file->f_mode |= FMODE_CREATED;
                error = finish_open(file, dentry, gfs2_open_common);
@@ -772,15 +772,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        gfs2_glock_dq_uninit(ghs);
        gfs2_glock_dq_uninit(ghs + 1);
        clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
+       gfs2_glock_put(io_gl);
        return error;
 
 fail_gunlock3:
        glock_clear_object(io_gl, ip);
        gfs2_glock_dq_uninit(&ip->i_iopen_gh);
-       gfs2_glock_put(io_gl);
 fail_gunlock2:
-       if (io_gl)
-               clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
+       clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
+       gfs2_glock_put(io_gl);
 fail_free_inode:
        if (ip->i_gl) {
                glock_clear_object(ip->i_gl, ip);
@@ -1475,7 +1475,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                        error = -EEXIST;
                default:
                        goto out_gunlock;
-               };
+               }
 
                if (odip != ndip) {
                        if (!ndip->i_inode.i_nlink) {
index 58e237f..eb3f2e7 100644 (file)
@@ -31,6 +31,8 @@
 #include "dir.h"
 #include "trace_gfs2.h"
 
+static void gfs2_log_shutdown(struct gfs2_sbd *sdp);
+
 /**
  * gfs2_struct2blk - compute stuff
  * @sdp: the filesystem
@@ -159,7 +161,8 @@ restart:
        list_for_each_entry_reverse(tr, head, tr_list) {
                if (wbc->nr_to_write <= 0)
                        break;
-               if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw))
+               if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw) &&
+                   !gfs2_withdrawn(sdp))
                        goto restart;
        }
        spin_unlock(&sdp->sd_ail_lock);
@@ -609,6 +612,14 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
        list_add(&bd->bd_list, &sdp->sd_log_revokes);
 }
 
+void gfs2_glock_remove_revoke(struct gfs2_glock *gl)
+{
+       if (atomic_dec_return(&gl->gl_revokes) == 0) {
+               clear_bit(GLF_LFLUSH, &gl->gl_flags);
+               gfs2_glock_queue_put(gl);
+       }
+}
+
 void gfs2_write_revokes(struct gfs2_sbd *sdp)
 {
        struct gfs2_trans *tr;
@@ -682,12 +693,16 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
 {
        struct gfs2_log_header *lh;
        u32 hash, crc;
-       struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
+       struct page *page;
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
        struct timespec64 tv;
        struct super_block *sb = sdp->sd_vfs;
        u64 dblock;
 
+       if (gfs2_withdrawn(sdp))
+               goto out;
+
+       page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
        lh = page_address(page);
        clear_page(lh);
 
@@ -707,7 +722,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
        lh->lh_nsec = cpu_to_be32(tv.tv_nsec);
        lh->lh_sec = cpu_to_be64(tv.tv_sec);
        if (!list_empty(&jd->extent_list))
-               dblock = gfs2_log_bmap(sdp);
+               dblock = gfs2_log_bmap(jd, lblock);
        else {
                int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock);
                if (gfs2_assert_withdraw(sdp, ret == 0))
@@ -740,6 +755,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
 
        gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
        gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE | op_flags);
+out:
        log_flush_wait(sdp);
 }
 
@@ -768,6 +784,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
        sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
        gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail,
                              sdp->sd_log_flush_head, flags, op_flags);
+       gfs2_log_incr_head(sdp);
 
        if (sdp->sd_log_tail != tail)
                log_pull_tail(sdp, tail);
@@ -948,7 +965,7 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
  *
  */
 
-void gfs2_log_shutdown(struct gfs2_sbd *sdp)
+static void gfs2_log_shutdown(struct gfs2_sbd *sdp)
 {
        gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved);
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
index 2315fca..2ff163a 100644 (file)
@@ -74,9 +74,9 @@ extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
 extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
 extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc);
 
-extern void gfs2_log_shutdown(struct gfs2_sbd *sdp);
 extern int gfs2_logd(void *data);
 extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd);
+extern void gfs2_glock_remove_revoke(struct gfs2_glock *gl);
 extern void gfs2_write_revokes(struct gfs2_sbd *sdp);
 
 #endif /* __LOG_DOT_H__ */
index 5b17979..55fed7d 100644 (file)
@@ -129,7 +129,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
        atomic_dec(&sdp->sd_log_pinned);
 }
 
-static void gfs2_log_incr_head(struct gfs2_sbd *sdp)
+void gfs2_log_incr_head(struct gfs2_sbd *sdp)
 {
        BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) &&
               (sdp->sd_log_flush_head != sdp->sd_log_head));
@@ -138,18 +138,13 @@ static void gfs2_log_incr_head(struct gfs2_sbd *sdp)
                sdp->sd_log_flush_head = 0;
 }
 
-u64 gfs2_log_bmap(struct gfs2_sbd *sdp)
+u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lblock)
 {
-       unsigned int lbn = sdp->sd_log_flush_head;
        struct gfs2_journal_extent *je;
-       u64 block;
 
-       list_for_each_entry(je, &sdp->sd_jdesc->extent_list, list) {
-               if ((lbn >= je->lblock) && (lbn < (je->lblock + je->blocks))) {
-                       block = je->dblock + lbn - je->lblock;
-                       gfs2_log_incr_head(sdp);
-                       return block;
-               }
+       list_for_each_entry(je, &jd->extent_list, list) {
+               if (lblock >= je->lblock && lblock < je->lblock + je->blocks)
+                       return je->dblock + lblock - je->lblock;
        }
 
        return -1;
@@ -351,8 +346,11 @@ void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
 
 static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh)
 {
-       gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh),
-                      gfs2_log_bmap(sdp));
+       u64 dblock;
+
+       dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head);
+       gfs2_log_incr_head(sdp);
+       gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh), dblock);
 }
 
 /**
@@ -369,8 +367,11 @@ static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh)
 void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page)
 {
        struct super_block *sb = sdp->sd_vfs;
-       gfs2_log_write(sdp, page, sb->s_blocksize, 0,
-                      gfs2_log_bmap(sdp));
+       u64 dblock;
+
+       dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head);
+       gfs2_log_incr_head(sdp);
+       gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
 }
 
 /**
@@ -882,10 +883,7 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
                bd = list_entry(head->next, struct gfs2_bufdata, bd_list);
                list_del_init(&bd->bd_list);
                gl = bd->bd_gl;
-               if (atomic_dec_return(&gl->gl_revokes) == 0) {
-                       clear_bit(GLF_LFLUSH, &gl->gl_flags);
-                       gfs2_glock_queue_put(gl);
-               }
+               gfs2_glock_remove_revoke(gl);
                kmem_cache_free(gfs2_bufdata_cachep, bd);
        }
 }
index 9c05995..9c5e4e4 100644 (file)
@@ -18,7 +18,8 @@
         ~(2 * sizeof(__be64) - 1))
 
 extern const struct gfs2_log_operations *gfs2_log_ops[];
-extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp);
+extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
+extern u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lbn);
 extern void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
                           unsigned size, unsigned offset, u64 blkno);
 extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page);
index 662ef36..0c37729 100644 (file)
@@ -251,7 +251,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
        struct buffer_head *bh, *bhs[2];
        int num = 0;
 
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) {
+       if (unlikely(gfs2_withdrawn(sdp))) {
                *bhp = NULL;
                return -EIO;
        }
@@ -309,7 +309,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
 
 int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
 {
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)))
+       if (unlikely(gfs2_withdrawn(sdp)))
                return -EIO;
 
        wait_on_buffer(bh);
@@ -320,7 +320,7 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
                        gfs2_io_error_bh_wd(sdp, bh);
                return -EIO;
        }
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)))
+       if (unlikely(gfs2_withdrawn(sdp)))
                return -EIO;
 
        return 0;
index 18daf49..e8b7b0c 100644 (file)
@@ -1006,8 +1006,7 @@ hostdata_error:
 void gfs2_lm_unmount(struct gfs2_sbd *sdp)
 {
        const struct lm_lockops *lm = sdp->sd_lockstruct.ls_ops;
-       if (likely(!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) &&
-           lm->lm_unmount)
+       if (likely(!gfs2_withdrawn(sdp)) && lm->lm_unmount)
                lm->lm_unmount(sdp);
 }
 
@@ -1328,7 +1327,7 @@ static const struct fs_parameter_enum gfs2_param_enums[] = {
        {}
 };
 
-const struct fs_parameter_description gfs2_fs_parameters = {
+static const struct fs_parameter_description gfs2_fs_parameters = {
        .name = "gfs2",
        .specs = gfs2_param_specs,
        .enums = gfs2_param_enums,
index 7c016a0..e9f9304 100644 (file)
@@ -1273,7 +1273,7 @@ int gfs2_quota_sync(struct super_block *sb, int type)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
        struct gfs2_quota_data **qda;
-       unsigned int max_qd = PAGE_SIZE/sizeof(struct gfs2_holder);
+       unsigned int max_qd = PAGE_SIZE / sizeof(struct gfs2_holder);
        unsigned int num_qd;
        unsigned int x;
        int error = 0;
@@ -1475,7 +1475,7 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error)
 {
        if (error == 0 || error == -EROFS)
                return;
-       if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) {
+       if (!gfs2_withdrawn(sdp)) {
                fs_err(sdp, "gfs2_quotad: %s error %d\n", msg, error);
                sdp->sd_log_error = error;
                wake_up(&sdp->sd_logd_waitq);
index c529f87..85f830e 100644 (file)
@@ -263,11 +263,13 @@ static void clean_journal(struct gfs2_jdesc *jd,
        u32 lblock = head->lh_blkno;
 
        gfs2_replay_incr_blk(jd, &lblock);
-       if (jd->jd_jid == sdp->sd_lockstruct.ls_jid)
-               sdp->sd_log_flush_head = lblock;
        gfs2_write_log_header(sdp, jd, head->lh_sequence + 1, 0, lblock,
                              GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_RECOVERY,
                              REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC);
+       if (jd->jd_jid == sdp->sd_lockstruct.ls_jid) {
+               sdp->sd_log_flush_head = lblock;
+               gfs2_log_incr_head(sdp);
+       }
 }
 
 
@@ -326,7 +328,7 @@ void gfs2_recover_func(struct work_struct *work)
 
                default:
                        goto fail;
-               };
+               }
 
                error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
                                           LM_FLAG_NOEXP | GL_NOCACHE, &ji_gh);
index 5fa1eec..68cc7c2 100644 (file)
@@ -399,8 +399,7 @@ struct lfcc {
  * Returns: errno
  */
 
-static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
-                                   struct gfs2_holder *freeze_gh)
+static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp)
 {
        struct gfs2_inode *ip;
        struct gfs2_jdesc *jd;
@@ -425,7 +424,9 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
        }
 
        error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE,
-                                  GL_NOCACHE, freeze_gh);
+                                  GL_NOCACHE, &sdp->sd_freeze_gh);
+       if (error)
+               goto out;
 
        list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
                error = gfs2_jdesc_check(jd);
@@ -441,7 +442,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
        }
 
        if (error)
-               gfs2_glock_dq_uninit(freeze_gh);
+               gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
 
 out:
        while (!list_empty(&list)) {
@@ -553,7 +554,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
 
        if (!(flags & I_DIRTY_INODE))
                return;
-       if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)))
+       if (unlikely(gfs2_withdrawn(sdp)))
                return;
        if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
                ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
@@ -602,7 +603,7 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
 
        error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE,
                                   &freeze_gh);
-       if (error && !test_bit(SDF_WITHDRAWN, &sdp->sd_flags))
+       if (error && !gfs2_withdrawn(sdp))
                return error;
 
        flush_workqueue(gfs2_delete_workqueue);
@@ -761,21 +762,25 @@ static int gfs2_freeze(struct super_block *sb)
        if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN)
                goto out;
 
-       if (test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) {
-               error = -EINVAL;
-               goto out;
-       }
-
        for (;;) {
-               error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh);
+               if (gfs2_withdrawn(sdp)) {
+                       error = -EINVAL;
+                       goto out;
+               }
+
+               error = gfs2_lock_fs_check_clean(sdp);
                if (!error)
                        break;
 
                if (error == -EBUSY)
                        fs_err(sdp, "waiting for recovery before freeze\n");
-               else
+               else if (error == -EIO) {
+                       fs_err(sdp, "Fatal IO error: cannot freeze gfs2 due "
+                              "to recovery error.\n");
+                       goto out;
+               } else {
                        fs_err(sdp, "error freezing FS: %d\n", error);
-
+               }
                fs_err(sdp, "retrying...\n");
                msleep(1000);
        }
index dd15b8e..8ccb68f 100644 (file)
@@ -118,7 +118,7 @@ static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
 
 static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf)
 {
-       unsigned int b = test_bit(SDF_WITHDRAWN, &sdp->sd_flags);
+       unsigned int b = gfs2_withdrawn(sdp);
        return snprintf(buf, PAGE_SIZE, "%u\n", b);
 }
 
index 35e3059..9d42273 100644 (file)
@@ -262,6 +262,8 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len)
                        list_del_init(&bd->bd_list);
                        gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke);
                        sdp->sd_log_num_revoke--;
+                       if (bd->bd_gl)
+                               gfs2_glock_remove_revoke(bd->bd_gl);
                        kmem_cache_free(gfs2_bufdata_cachep, bd);
                        tr->tr_num_revoke--;
                        if (--n == 0)
index c451591..ec600b4 100644 (file)
@@ -258,7 +258,7 @@ void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
                        const char *function, char *file, unsigned int line,
                        bool withdraw)
 {
-       if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags))
+       if (!gfs2_withdrawn(sdp))
                fs_err(sdp,
                       "fatal: I/O error\n"
                       "  block = %llu\n"
index 4b68b2c..f2702bc 100644 (file)
@@ -164,6 +164,15 @@ static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt,
        return x;
 }
 
+/**
+ * gfs2_withdrawn - test whether the file system is withdrawing or withdrawn
+ * @sdp: the superblock
+ */
+static inline bool gfs2_withdrawn(struct gfs2_sbd *sdp)
+{
+       return test_bit(SDF_WITHDRAWN, &sdp->sd_flags);
+}
+
 #define gfs2_tune_get(sdp, field) \
 gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field)
 
index 315fcd8..4a7da1d 100644 (file)
@@ -151,7 +151,6 @@ extern int invalidate_inodes(struct super_block *, bool);
 /*
  * dcache.c
  */
-extern struct dentry *__d_alloc(struct super_block *, const struct qstr *);
 extern int d_set_mounted(struct dentry *dentry);
 extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc);
 extern struct dentry *d_alloc_cursor(struct dentry *);
index 91b85df..90c4978 100644 (file)
@@ -49,7 +49,6 @@ struct io_worker {
        struct hlist_nulls_node nulls_node;
        struct list_head all_list;
        struct task_struct *task;
-       wait_queue_head_t wait;
        struct io_wqe *wqe;
 
        struct io_wq_work *cur_work;
@@ -111,7 +110,7 @@ struct io_wq {
 
        struct task_struct *manager;
        struct user_struct *user;
-       struct cred *creds;
+       const struct cred *creds;
        struct mm_struct *mm;
        refcount_t refs;
        struct completion done;
@@ -258,7 +257,7 @@ static bool io_wqe_activate_free_worker(struct io_wqe *wqe)
 
        worker = hlist_nulls_entry(n, struct io_worker, nulls_node);
        if (io_worker_get(worker)) {
-               wake_up(&worker->wait);
+               wake_up_process(worker->task);
                io_worker_release(worker);
                return true;
        }
@@ -492,28 +491,46 @@ next:
        } while (1);
 }
 
+static inline void io_worker_spin_for_work(struct io_wqe *wqe)
+{
+       int i = 0;
+
+       while (++i < 1000) {
+               if (io_wqe_run_queue(wqe))
+                       break;
+               if (need_resched())
+                       break;
+               cpu_relax();
+       }
+}
+
 static int io_wqe_worker(void *data)
 {
        struct io_worker *worker = data;
        struct io_wqe *wqe = worker->wqe;
        struct io_wq *wq = wqe->wq;
-       DEFINE_WAIT(wait);
+       bool did_work;
 
        io_worker_start(wqe, worker);
 
+       did_work = false;
        while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) {
-               prepare_to_wait(&worker->wait, &wait, TASK_INTERRUPTIBLE);
-
+               set_current_state(TASK_INTERRUPTIBLE);
+loop:
+               if (did_work)
+                       io_worker_spin_for_work(wqe);
                spin_lock_irq(&wqe->lock);
                if (io_wqe_run_queue(wqe)) {
                        __set_current_state(TASK_RUNNING);
                        io_worker_handle_work(worker);
-                       continue;
+                       did_work = true;
+                       goto loop;
                }
+               did_work = false;
                /* drops the lock on success, retry */
                if (__io_worker_idle(wqe, worker)) {
                        __release(&wqe->lock);
-                       continue;
+                       goto loop;
                }
                spin_unlock_irq(&wqe->lock);
                if (signal_pending(current))
@@ -526,8 +543,6 @@ static int io_wqe_worker(void *data)
                        break;
        }
 
-       finish_wait(&worker->wait, &wait);
-
        if (test_bit(IO_WQ_BIT_EXIT, &wq->state)) {
                spin_lock_irq(&wqe->lock);
                if (!wq_list_empty(&wqe->work_list))
@@ -589,7 +604,6 @@ static bool create_io_worker(struct io_wq *wq, struct io_wqe *wqe, int index)
 
        refcount_set(&worker->ref, 1);
        worker->nulls_node.pprev = NULL;
-       init_waitqueue_head(&worker->wait);
        worker->wqe = wqe;
        spin_lock_init(&worker->lock);
 
index 600e015..fb993b2 100644 (file)
@@ -35,7 +35,8 @@ static inline void wq_list_add_tail(struct io_wq_work_node *node,
                                    struct io_wq_work_list *list)
 {
        if (!list->first) {
-               list->first = list->last = node;
+               list->last = node;
+               WRITE_ONCE(list->first, node);
        } else {
                list->last->next = node;
                list->last = node;
@@ -47,17 +48,18 @@ static inline void wq_node_del(struct io_wq_work_list *list,
                               struct io_wq_work_node *prev)
 {
        if (node == list->first)
-               list->first = node->next;
+               WRITE_ONCE(list->first, node->next);
        if (node == list->last)
                list->last = prev;
        if (prev)
                prev->next = node->next;
+       node->next = NULL;
 }
 
 #define wq_list_for_each(pos, prv, head)                       \
        for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next)
 
-#define wq_list_empty(list)    ((list)->first == NULL)
+#define wq_list_empty(list)    (READ_ONCE((list)->first) == NULL)
 #define INIT_WQ_LIST(list)     do {                            \
        (list)->first = NULL;                                   \
        (list)->last = NULL;                                    \
@@ -87,7 +89,7 @@ typedef void (put_work_fn)(struct io_wq_work *);
 struct io_wq_data {
        struct mm_struct *mm;
        struct user_struct *user;
-       struct cred *creds;
+       const struct cred *creds;
 
        get_work_fn *get_work;
        put_work_fn *put_work;
@@ -118,10 +120,6 @@ static inline void io_wq_worker_sleeping(struct task_struct *tsk)
 static inline void io_wq_worker_running(struct task_struct *tsk)
 {
 }
-#endif
+#endif /* CONFIG_IO_WQ */
 
-static inline bool io_wq_current_is_worker(void)
-{
-       return in_task() && (current->flags & PF_IO_WORKER);
-}
-#endif
+#endif /* INTERNAL_IO_WQ_H */
index ec53aa7..9b1833f 100644 (file)
@@ -145,7 +145,7 @@ struct io_rings {
        /*
         * Number of completion events lost because the queue was full;
         * this should be avoided by the application by making sure
-        * there are not more requests pending thatn there is space in
+        * there are not more requests pending than there is space in
         * the completion queue.
         *
         * Written by the kernel, shouldn't be modified by the
@@ -238,7 +238,7 @@ struct io_ring_ctx {
 
        struct user_struct      *user;
 
-       struct cred             *creds;
+       const struct cred       *creds;
 
        /* 0 is for ctx quiesce/reinit/free, 1 is for sqo_thread started */
        struct completion       *completions;
@@ -275,7 +275,8 @@ struct io_ring_ctx {
                 * manipulate the list, hence no extra locking is needed there.
                 */
                struct list_head        poll_list;
-               struct rb_root          cancel_tree;
+               struct hlist_head       *cancel_hash;
+               unsigned                cancel_hash_bits;
 
                spinlock_t              inflight_lock;
                struct list_head        inflight_list;
@@ -292,7 +293,7 @@ struct io_poll_iocb {
        __poll_t                        events;
        bool                            done;
        bool                            canceled;
-       struct wait_queue_entry         *wait;
+       struct wait_queue_entry         wait;
 };
 
 struct io_timeout_data {
@@ -303,9 +304,32 @@ struct io_timeout_data {
        u32                             seq_offset;
 };
 
-struct io_timeout {
-       struct file                     *file;
-       struct io_timeout_data          *data;
+struct io_async_connect {
+       struct sockaddr_storage         address;
+};
+
+struct io_async_msghdr {
+       struct iovec                    fast_iov[UIO_FASTIOV];
+       struct iovec                    *iov;
+       struct sockaddr __user          *uaddr;
+       struct msghdr                   msg;
+};
+
+struct io_async_rw {
+       struct iovec                    fast_iov[UIO_FASTIOV];
+       struct iovec                    *iov;
+       ssize_t                         nr_segs;
+       ssize_t                         size;
+};
+
+struct io_async_ctx {
+       struct io_uring_sqe             sqe;
+       union {
+               struct io_async_rw      rw;
+               struct io_async_msghdr  msg;
+               struct io_async_connect connect;
+               struct io_timeout_data  timeout;
+       };
 };
 
 /*
@@ -319,10 +343,10 @@ struct io_kiocb {
                struct file             *file;
                struct kiocb            rw;
                struct io_poll_iocb     poll;
-               struct io_timeout       timeout;
        };
 
        const struct io_uring_sqe       *sqe;
+       struct io_async_ctx             *io;
        struct file                     *ring_file;
        int                             ring_fd;
        bool                            has_user;
@@ -332,7 +356,7 @@ struct io_kiocb {
        struct io_ring_ctx      *ctx;
        union {
                struct list_head        list;
-               struct rb_node          rb_node;
+               struct hlist_node       hash_node;
        };
        struct list_head        link_list;
        unsigned int            flags;
@@ -353,7 +377,7 @@ struct io_kiocb {
 #define REQ_F_TIMEOUT_NOSEQ    8192    /* no timeout sequence */
 #define REQ_F_INFLIGHT         16384   /* on inflight list */
 #define REQ_F_COMP_LOCKED      32768   /* completion under lock */
-#define REQ_F_FREE_SQE         65536   /* free sqe if not async queued */
+#define REQ_F_HARDLINK         65536   /* doesn't sever on completion < 0 */
        u64                     user_data;
        u32                     result;
        u32                     sequence;
@@ -422,6 +446,7 @@ static void io_ring_ctx_ref_free(struct percpu_ref *ref)
 static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
 {
        struct io_ring_ctx *ctx;
+       int hash_bits;
 
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
@@ -435,6 +460,21 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
        if (!ctx->completions)
                goto err;
 
+       /*
+        * Use 5 bits less than the max cq entries, that should give us around
+        * 32 entries per hash list if totally full and uniformly spread.
+        */
+       hash_bits = ilog2(p->cq_entries);
+       hash_bits -= 5;
+       if (hash_bits <= 0)
+               hash_bits = 1;
+       ctx->cancel_hash_bits = hash_bits;
+       ctx->cancel_hash = kmalloc((1U << hash_bits) * sizeof(struct hlist_head),
+                                       GFP_KERNEL);
+       if (!ctx->cancel_hash)
+               goto err;
+       __hash_init(ctx->cancel_hash, 1U << hash_bits);
+
        if (percpu_ref_init(&ctx->refs, io_ring_ctx_ref_free,
                            PERCPU_REF_ALLOW_REINIT, GFP_KERNEL))
                goto err;
@@ -448,7 +488,6 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
        init_waitqueue_head(&ctx->wait);
        spin_lock_init(&ctx->completion_lock);
        INIT_LIST_HEAD(&ctx->poll_list);
-       ctx->cancel_tree = RB_ROOT;
        INIT_LIST_HEAD(&ctx->defer_list);
        INIT_LIST_HEAD(&ctx->timeout_list);
        init_waitqueue_head(&ctx->inflight_wait);
@@ -459,6 +498,7 @@ err:
        if (ctx->fallback_req)
                kmem_cache_free(req_cachep, ctx->fallback_req);
        kfree(ctx->completions);
+       kfree(ctx->cancel_hash);
        kfree(ctx);
        return NULL;
 }
@@ -541,7 +581,9 @@ static inline bool io_prep_async_work(struct io_kiocb *req,
                switch (req->sqe->opcode) {
                case IORING_OP_WRITEV:
                case IORING_OP_WRITE_FIXED:
-                       do_hashed = true;
+                       /* only regular files should be hashed for writes */
+                       if (req->flags & REQ_F_ISREG)
+                               do_hashed = true;
                        /* fall-through */
                case IORING_OP_READV:
                case IORING_OP_READ_FIXED:
@@ -592,7 +634,7 @@ static void io_kill_timeout(struct io_kiocb *req)
 {
        int ret;
 
-       ret = hrtimer_try_to_cancel(&req->timeout.data->timer);
+       ret = hrtimer_try_to_cancel(&req->io->timeout.timer);
        if (ret != -1) {
                atomic_inc(&req->ctx->cq_timeouts);
                list_del_init(&req->list);
@@ -806,6 +848,7 @@ static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx,
        }
 
 got_it:
+       req->io = NULL;
        req->ring_file = NULL;
        req->file = NULL;
        req->ctx = ctx;
@@ -836,8 +879,8 @@ static void __io_free_req(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
 
-       if (req->flags & REQ_F_FREE_SQE)
-               kfree(req->sqe);
+       if (req->io)
+               kfree(req->io);
        if (req->file && !(req->flags & REQ_F_FIXED_FILE))
                fput(req->file);
        if (req->flags & REQ_F_INFLIGHT) {
@@ -849,8 +892,6 @@ static void __io_free_req(struct io_kiocb *req)
                        wake_up(&ctx->inflight_wait);
                spin_unlock_irqrestore(&ctx->inflight_lock, flags);
        }
-       if (req->flags & REQ_F_TIMEOUT)
-               kfree(req->timeout.data);
        percpu_ref_put(&ctx->refs);
        if (likely(!io_is_fallback_req(req)))
                kmem_cache_free(req_cachep, req);
@@ -863,7 +904,7 @@ static bool io_link_cancel_timeout(struct io_kiocb *req)
        struct io_ring_ctx *ctx = req->ctx;
        int ret;
 
-       ret = hrtimer_try_to_cancel(&req->timeout.data->timer);
+       ret = hrtimer_try_to_cancel(&req->io->timeout.timer);
        if (ret != -1) {
                io_cqring_fill_event(req, -ECANCELED);
                io_commit_cqring(ctx);
@@ -878,7 +919,6 @@ static bool io_link_cancel_timeout(struct io_kiocb *req)
 static void io_req_link_next(struct io_kiocb *req, struct io_kiocb **nxtptr)
 {
        struct io_ring_ctx *ctx = req->ctx;
-       struct io_kiocb *nxt;
        bool wake_ev = false;
 
        /* Already got next link */
@@ -890,24 +930,21 @@ static void io_req_link_next(struct io_kiocb *req, struct io_kiocb **nxtptr)
         * potentially happen if the chain is messed up, check to be on the
         * safe side.
         */
-       nxt = list_first_entry_or_null(&req->link_list, struct io_kiocb, list);
-       while (nxt) {
-               list_del_init(&nxt->list);
+       while (!list_empty(&req->link_list)) {
+               struct io_kiocb *nxt = list_first_entry(&req->link_list,
+                                               struct io_kiocb, link_list);
 
-               if ((req->flags & REQ_F_LINK_TIMEOUT) &&
-                   (nxt->flags & REQ_F_TIMEOUT)) {
+               if (unlikely((req->flags & REQ_F_LINK_TIMEOUT) &&
+                            (nxt->flags & REQ_F_TIMEOUT))) {
+                       list_del_init(&nxt->link_list);
                        wake_ev |= io_link_cancel_timeout(nxt);
-                       nxt = list_first_entry_or_null(&req->link_list,
-                                                       struct io_kiocb, list);
                        req->flags &= ~REQ_F_LINK_TIMEOUT;
                        continue;
                }
-               if (!list_empty(&req->link_list)) {
-                       INIT_LIST_HEAD(&nxt->link_list);
-                       list_splice(&req->link_list, &nxt->link_list);
-                       nxt->flags |= REQ_F_LINK;
-               }
 
+               list_del_init(&req->link_list);
+               if (!list_empty(&nxt->link_list))
+                       nxt->flags |= REQ_F_LINK;
                *nxtptr = nxt;
                break;
        }
@@ -923,15 +960,15 @@ static void io_req_link_next(struct io_kiocb *req, struct io_kiocb **nxtptr)
 static void io_fail_links(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
-       struct io_kiocb *link;
        unsigned long flags;
 
        spin_lock_irqsave(&ctx->completion_lock, flags);
 
        while (!list_empty(&req->link_list)) {
-               link = list_first_entry(&req->link_list, struct io_kiocb, list);
-               list_del_init(&link->list);
+               struct io_kiocb *link = list_first_entry(&req->link_list,
+                                               struct io_kiocb, link_list);
 
+               list_del_init(&link->link_list);
                trace_io_uring_fail_link(req, link);
 
                if ((req->flags & REQ_F_LINK_TIMEOUT) &&
@@ -1079,9 +1116,9 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events,
                         * completions for those, only batch free for fixed
                         * file and non-linked commands.
                         */
-                       if (((req->flags &
-                               (REQ_F_FIXED_FILE|REQ_F_LINK|REQ_F_FREE_SQE)) ==
-                           REQ_F_FIXED_FILE) && !io_is_fallback_req(req)) {
+                       if (((req->flags & (REQ_F_FIXED_FILE|REQ_F_LINK)) ==
+                           REQ_F_FIXED_FILE) && !io_is_fallback_req(req) &&
+                           !req->io) {
                                reqs[to_free++] = req;
                                if (to_free == ARRAY_SIZE(reqs))
                                        io_free_req_many(ctx, reqs, &to_free);
@@ -1258,6 +1295,12 @@ static void kiocb_end_write(struct io_kiocb *req)
        file_end_write(req->file);
 }
 
+static inline void req_set_fail_links(struct io_kiocb *req)
+{
+       if ((req->flags & (REQ_F_LINK | REQ_F_HARDLINK)) == REQ_F_LINK)
+               req->flags |= REQ_F_FAIL_LINK;
+}
+
 static void io_complete_rw_common(struct kiocb *kiocb, long res)
 {
        struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw);
@@ -1265,8 +1308,8 @@ static void io_complete_rw_common(struct kiocb *kiocb, long res)
        if (kiocb->ki_flags & IOCB_WRITE)
                kiocb_end_write(req);
 
-       if ((req->flags & REQ_F_LINK) && res != req->result)
-               req->flags |= REQ_F_FAIL_LINK;
+       if (res != req->result)
+               req_set_fail_links(req);
        io_cqring_add_event(req, res);
 }
 
@@ -1296,8 +1339,8 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2)
        if (kiocb->ki_flags & IOCB_WRITE)
                kiocb_end_write(req);
 
-       if ((req->flags & REQ_F_LINK) && res != req->result)
-               req->flags |= REQ_F_FAIL_LINK;
+       if (res != req->result)
+               req_set_fail_links(req);
        req->result = res;
        if (res != -EAGAIN)
                req->flags |= REQ_F_IOPOLL_COMPLETED;
@@ -1388,7 +1431,7 @@ static bool io_file_supports_async(struct file *file)
 {
        umode_t mode = file_inode(file)->i_mode;
 
-       if (S_ISBLK(mode) || S_ISCHR(mode))
+       if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISSOCK(mode))
                return true;
        if (S_ISREG(mode) && file->f_op != &io_uring_fops)
                return true;
@@ -1410,15 +1453,6 @@ static int io_prep_rw(struct io_kiocb *req, bool force_nonblock)
        if (S_ISREG(file_inode(req->file)->i_mode))
                req->flags |= REQ_F_ISREG;
 
-       /*
-        * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so
-        * we know to async punt it even if it was opened O_NONBLOCK
-        */
-       if (force_nonblock && !io_file_supports_async(req->file)) {
-               req->flags |= REQ_F_MUST_PUNT;
-               return -EAGAIN;
-       }
-
        kiocb->ki_pos = READ_ONCE(sqe->off);
        kiocb->ki_flags = iocb_flags(kiocb->ki_filp);
        kiocb->ki_hint = ki_hint_validate(file_write_hint(kiocb->ki_filp));
@@ -1587,6 +1621,16 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
                return io_import_fixed(req->ctx, rw, sqe, iter);
        }
 
+       if (req->io) {
+               struct io_async_rw *iorw = &req->io->rw;
+
+               *iovec = iorw->iov;
+               iov_iter_init(iter, rw, *iovec, iorw->nr_segs, iorw->size);
+               if (iorw->iov == iorw->fast_iov)
+                       *iovec = NULL;
+               return iorw->size;
+       }
+
        if (!req->has_user)
                return -EFAULT;
 
@@ -1657,6 +1701,50 @@ static ssize_t loop_rw_iter(int rw, struct file *file, struct kiocb *kiocb,
        return ret;
 }
 
+static void io_req_map_io(struct io_kiocb *req, ssize_t io_size,
+                         struct iovec *iovec, struct iovec *fast_iov,
+                         struct iov_iter *iter)
+{
+       req->io->rw.nr_segs = iter->nr_segs;
+       req->io->rw.size = io_size;
+       req->io->rw.iov = iovec;
+       if (!req->io->rw.iov) {
+               req->io->rw.iov = req->io->rw.fast_iov;
+               memcpy(req->io->rw.iov, fast_iov,
+                       sizeof(struct iovec) * iter->nr_segs);
+       }
+}
+
+static int io_setup_async_io(struct io_kiocb *req, ssize_t io_size,
+                            struct iovec *iovec, struct iovec *fast_iov,
+                            struct iov_iter *iter)
+{
+       req->io = kmalloc(sizeof(*req->io), GFP_KERNEL);
+       if (req->io) {
+               io_req_map_io(req, io_size, iovec, fast_iov, iter);
+               memcpy(&req->io->sqe, req->sqe, sizeof(req->io->sqe));
+               req->sqe = &req->io->sqe;
+               return 0;
+       }
+
+       return -ENOMEM;
+}
+
+static int io_read_prep(struct io_kiocb *req, struct iovec **iovec,
+                       struct iov_iter *iter, bool force_nonblock)
+{
+       ssize_t ret;
+
+       ret = io_prep_rw(req, force_nonblock);
+       if (ret)
+               return ret;
+
+       if (unlikely(!(req->file->f_mode & FMODE_READ)))
+               return -EBADF;
+
+       return io_import_iovec(READ, req, iovec, iter);
+}
+
 static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
                   bool force_nonblock)
 {
@@ -1665,23 +1753,31 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
        struct iov_iter iter;
        struct file *file;
        size_t iov_count;
-       ssize_t read_size, ret;
-
-       ret = io_prep_rw(req, force_nonblock);
-       if (ret)
-               return ret;
-       file = kiocb->ki_filp;
+       ssize_t io_size, ret;
 
-       if (unlikely(!(file->f_mode & FMODE_READ)))
-               return -EBADF;
-
-       ret = io_import_iovec(READ, req, &iovec, &iter);
-       if (ret < 0)
-               return ret;
+       if (!req->io) {
+               ret = io_read_prep(req, &iovec, &iter, force_nonblock);
+               if (ret < 0)
+                       return ret;
+       } else {
+               ret = io_import_iovec(READ, req, &iovec, &iter);
+               if (ret < 0)
+                       return ret;
+       }
 
-       read_size = ret;
+       file = req->file;
+       io_size = ret;
        if (req->flags & REQ_F_LINK)
-               req->result = read_size;
+               req->result = io_size;
+
+       /*
+        * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so
+        * we know to async punt it even if it was opened O_NONBLOCK
+        */
+       if (force_nonblock && !io_file_supports_async(file)) {
+               req->flags |= REQ_F_MUST_PUNT;
+               goto copy_iov;
+       }
 
        iov_count = iov_iter_count(&iter);
        ret = rw_verify_area(READ, file, &kiocb->ki_pos, iov_count);
@@ -1703,18 +1799,40 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
                 */
                if (force_nonblock && !(req->flags & REQ_F_NOWAIT) &&
                    (req->flags & REQ_F_ISREG) &&
-                   ret2 > 0 && ret2 < read_size)
+                   ret2 > 0 && ret2 < io_size)
                        ret2 = -EAGAIN;
                /* Catch -EAGAIN return for forced non-blocking submission */
-               if (!force_nonblock || ret2 != -EAGAIN)
+               if (!force_nonblock || ret2 != -EAGAIN) {
                        kiocb_done(kiocb, ret2, nxt, req->in_async);
-               else
-                       ret = -EAGAIN;
+               } else {
+copy_iov:
+                       ret = io_setup_async_io(req, io_size, iovec,
+                                               inline_vecs, &iter);
+                       if (ret)
+                               goto out_free;
+                       return -EAGAIN;
+               }
        }
+out_free:
        kfree(iovec);
        return ret;
 }
 
+static int io_write_prep(struct io_kiocb *req, struct iovec **iovec,
+                        struct iov_iter *iter, bool force_nonblock)
+{
+       ssize_t ret;
+
+       ret = io_prep_rw(req, force_nonblock);
+       if (ret)
+               return ret;
+
+       if (unlikely(!(req->file->f_mode & FMODE_WRITE)))
+               return -EBADF;
+
+       return io_import_iovec(WRITE, req, iovec, iter);
+}
+
 static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
                    bool force_nonblock)
 {
@@ -1723,29 +1841,38 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
        struct iov_iter iter;
        struct file *file;
        size_t iov_count;
-       ssize_t ret;
+       ssize_t ret, io_size;
 
-       ret = io_prep_rw(req, force_nonblock);
-       if (ret)
-               return ret;
+       if (!req->io) {
+               ret = io_write_prep(req, &iovec, &iter, force_nonblock);
+               if (ret < 0)
+                       return ret;
+       } else {
+               ret = io_import_iovec(WRITE, req, &iovec, &iter);
+               if (ret < 0)
+                       return ret;
+       }
 
        file = kiocb->ki_filp;
-       if (unlikely(!(file->f_mode & FMODE_WRITE)))
-               return -EBADF;
-
-       ret = io_import_iovec(WRITE, req, &iovec, &iter);
-       if (ret < 0)
-               return ret;
-
+       io_size = ret;
        if (req->flags & REQ_F_LINK)
-               req->result = ret;
+               req->result = io_size;
 
-       iov_count = iov_iter_count(&iter);
+       /*
+        * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so
+        * we know to async punt it even if it was opened O_NONBLOCK
+        */
+       if (force_nonblock && !io_file_supports_async(req->file)) {
+               req->flags |= REQ_F_MUST_PUNT;
+               goto copy_iov;
+       }
 
-       ret = -EAGAIN;
-       if (force_nonblock && !(kiocb->ki_flags & IOCB_DIRECT))
-               goto out_free;
+       /* file path doesn't support NOWAIT for non-direct_IO */
+       if (force_nonblock && !(kiocb->ki_flags & IOCB_DIRECT) &&
+           (req->flags & REQ_F_ISREG))
+               goto copy_iov;
 
+       iov_count = iov_iter_count(&iter);
        ret = rw_verify_area(WRITE, file, &kiocb->ki_pos, iov_count);
        if (!ret) {
                ssize_t ret2;
@@ -1769,10 +1896,16 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
                        ret2 = call_write_iter(file, kiocb, &iter);
                else
                        ret2 = loop_rw_iter(WRITE, file, kiocb, &iter);
-               if (!force_nonblock || ret2 != -EAGAIN)
+               if (!force_nonblock || ret2 != -EAGAIN) {
                        kiocb_done(kiocb, ret2, nxt, req->in_async);
-               else
-                       ret = -EAGAIN;
+               } else {
+copy_iov:
+                       ret = io_setup_async_io(req, io_size, iovec,
+                                               inline_vecs, &iter);
+                       if (ret)
+                               goto out_free;
+                       return -EAGAIN;
+               }
        }
 out_free:
        kfree(iovec);
@@ -1834,8 +1967,8 @@ static int io_fsync(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                                end > 0 ? end : LLONG_MAX,
                                fsync_flags & IORING_FSYNC_DATASYNC);
 
-       if (ret < 0 && (req->flags & REQ_F_LINK))
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_cqring_add_event(req, ret);
        io_put_req_find_next(req, nxt);
        return 0;
@@ -1881,19 +2014,33 @@ static int io_sync_file_range(struct io_kiocb *req,
 
        ret = sync_file_range(req->rw.ki_filp, sqe_off, sqe_len, flags);
 
-       if (ret < 0 && (req->flags & REQ_F_LINK))
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_cqring_add_event(req, ret);
        io_put_req_find_next(req, nxt);
        return 0;
 }
 
+static int io_sendmsg_prep(struct io_kiocb *req, struct io_async_ctx *io)
+{
 #if defined(CONFIG_NET)
-static int io_send_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe,
-                          struct io_kiocb **nxt, bool force_nonblock,
-                  long (*fn)(struct socket *, struct user_msghdr __user *,
-                               unsigned int))
+       const struct io_uring_sqe *sqe = req->sqe;
+       struct user_msghdr __user *msg;
+       unsigned flags;
+
+       flags = READ_ONCE(sqe->msg_flags);
+       msg = (struct user_msghdr __user *)(unsigned long) READ_ONCE(sqe->addr);
+       io->msg.iov = io->msg.fast_iov;
+       return sendmsg_copy_msghdr(&io->msg.msg, msg, flags, &io->msg.iov);
+#else
+       return 0;
+#endif
+}
+
+static int io_sendmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe,
+                     struct io_kiocb **nxt, bool force_nonblock)
 {
+#if defined(CONFIG_NET)
        struct socket *sock;
        int ret;
 
@@ -1902,7 +2049,9 @@ static int io_send_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 
        sock = sock_from_file(req->file, &ret);
        if (sock) {
-               struct user_msghdr __user *msg;
+               struct io_async_ctx io, *copy;
+               struct sockaddr_storage addr;
+               struct msghdr *kmsg;
                unsigned flags;
 
                flags = READ_ONCE(sqe->msg_flags);
@@ -1911,30 +2060,59 @@ static int io_send_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                else if (force_nonblock)
                        flags |= MSG_DONTWAIT;
 
-               msg = (struct user_msghdr __user *) (unsigned long)
-                       READ_ONCE(sqe->addr);
+               if (req->io) {
+                       kmsg = &req->io->msg.msg;
+                       kmsg->msg_name = &addr;
+               } else {
+                       kmsg = &io.msg.msg;
+                       kmsg->msg_name = &addr;
+                       ret = io_sendmsg_prep(req, &io);
+                       if (ret)
+                               goto out;
+               }
 
-               ret = fn(sock, msg, flags);
-               if (force_nonblock && ret == -EAGAIN)
+               ret = __sys_sendmsg_sock(sock, kmsg, flags);
+               if (force_nonblock && ret == -EAGAIN) {
+                       copy = kmalloc(sizeof(*copy), GFP_KERNEL);
+                       if (!copy) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       memcpy(&copy->msg, &io.msg, sizeof(copy->msg));
+                       req->io = copy;
+                       memcpy(&req->io->sqe, req->sqe, sizeof(*req->sqe));
+                       req->sqe = &req->io->sqe;
                        return ret;
+               }
+               if (ret == -ERESTARTSYS)
+                       ret = -EINTR;
        }
 
+out:
        io_cqring_add_event(req, ret);
-       if (ret < 0 && (req->flags & REQ_F_LINK))
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_put_req_find_next(req, nxt);
        return 0;
-}
+#else
+       return -EOPNOTSUPP;
 #endif
+}
 
-static int io_sendmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe,
-                     struct io_kiocb **nxt, bool force_nonblock)
+static int io_recvmsg_prep(struct io_kiocb *req, struct io_async_ctx *io)
 {
 #if defined(CONFIG_NET)
-       return io_send_recvmsg(req, sqe, nxt, force_nonblock,
-                               __sys_sendmsg_sock);
+       const struct io_uring_sqe *sqe = req->sqe;
+       struct user_msghdr __user *msg;
+       unsigned flags;
+
+       flags = READ_ONCE(sqe->msg_flags);
+       msg = (struct user_msghdr __user *)(unsigned long) READ_ONCE(sqe->addr);
+       io->msg.iov = io->msg.fast_iov;
+       return recvmsg_copy_msghdr(&io->msg.msg, msg, flags, &io->msg.uaddr,
+                                       &io->msg.iov);
 #else
-       return -EOPNOTSUPP;
+       return 0;
 #endif
 }
 
@@ -1942,8 +2120,62 @@ static int io_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                      struct io_kiocb **nxt, bool force_nonblock)
 {
 #if defined(CONFIG_NET)
-       return io_send_recvmsg(req, sqe, nxt, force_nonblock,
-                               __sys_recvmsg_sock);
+       struct socket *sock;
+       int ret;
+
+       if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
+               return -EINVAL;
+
+       sock = sock_from_file(req->file, &ret);
+       if (sock) {
+               struct user_msghdr __user *msg;
+               struct io_async_ctx io, *copy;
+               struct sockaddr_storage addr;
+               struct msghdr *kmsg;
+               unsigned flags;
+
+               flags = READ_ONCE(sqe->msg_flags);
+               if (flags & MSG_DONTWAIT)
+                       req->flags |= REQ_F_NOWAIT;
+               else if (force_nonblock)
+                       flags |= MSG_DONTWAIT;
+
+               msg = (struct user_msghdr __user *) (unsigned long)
+                       READ_ONCE(sqe->addr);
+               if (req->io) {
+                       kmsg = &req->io->msg.msg;
+                       kmsg->msg_name = &addr;
+               } else {
+                       kmsg = &io.msg.msg;
+                       kmsg->msg_name = &addr;
+                       ret = io_recvmsg_prep(req, &io);
+                       if (ret)
+                               goto out;
+               }
+
+               ret = __sys_recvmsg_sock(sock, kmsg, msg, io.msg.uaddr, flags);
+               if (force_nonblock && ret == -EAGAIN) {
+                       copy = kmalloc(sizeof(*copy), GFP_KERNEL);
+                       if (!copy) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       memcpy(copy, &io, sizeof(*copy));
+                       req->io = copy;
+                       memcpy(&req->io->sqe, req->sqe, sizeof(*req->sqe));
+                       req->sqe = &req->io->sqe;
+                       return ret;
+               }
+               if (ret == -ERESTARTSYS)
+                       ret = -EINTR;
+       }
+
+out:
+       io_cqring_add_event(req, ret);
+       if (ret < 0)
+               req_set_fail_links(req);
+       io_put_req_find_next(req, nxt);
+       return 0;
 #else
        return -EOPNOTSUPP;
 #endif
@@ -1975,8 +2207,8 @@ static int io_accept(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        }
        if (ret == -ERESTARTSYS)
                ret = -EINTR;
-       if (ret < 0 && (req->flags & REQ_F_LINK))
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_cqring_add_event(req, ret);
        io_put_req_find_next(req, nxt);
        return 0;
@@ -1985,11 +2217,26 @@ static int io_accept(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 #endif
 }
 
+static int io_connect_prep(struct io_kiocb *req, struct io_async_ctx *io)
+{
+#if defined(CONFIG_NET)
+       const struct io_uring_sqe *sqe = req->sqe;
+       struct sockaddr __user *addr;
+       int addr_len;
+
+       addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr);
+       addr_len = READ_ONCE(sqe->addr2);
+       return move_addr_to_kernel(addr, addr_len, &io->connect.address);
+#else
+       return 0;
+#endif
+}
+
 static int io_connect(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                      struct io_kiocb **nxt, bool force_nonblock)
 {
 #if defined(CONFIG_NET)
-       struct sockaddr __user *addr;
+       struct io_async_ctx __io, *io;
        unsigned file_flags;
        int addr_len, ret;
 
@@ -1998,17 +2245,37 @@ static int io_connect(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags)
                return -EINVAL;
 
-       addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr);
        addr_len = READ_ONCE(sqe->addr2);
        file_flags = force_nonblock ? O_NONBLOCK : 0;
 
-       ret = __sys_connect_file(req->file, addr, addr_len, file_flags);
-       if (ret == -EAGAIN && force_nonblock)
+       if (req->io) {
+               io = req->io;
+       } else {
+               ret = io_connect_prep(req, &__io);
+               if (ret)
+                       goto out;
+               io = &__io;
+       }
+
+       ret = __sys_connect_file(req->file, &io->connect.address, addr_len,
+                                       file_flags);
+       if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) {
+               io = kmalloc(sizeof(*io), GFP_KERNEL);
+               if (!io) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               memcpy(&io->connect, &__io.connect, sizeof(io->connect));
+               req->io = io;
+               memcpy(&io->sqe, req->sqe, sizeof(*req->sqe));
+               req->sqe = &io->sqe;
                return -EAGAIN;
+       }
        if (ret == -ERESTARTSYS)
                ret = -EINTR;
-       if (ret < 0 && (req->flags & REQ_F_LINK))
-               req->flags |= REQ_F_FAIL_LINK;
+out:
+       if (ret < 0)
+               req_set_fail_links(req);
        io_cqring_add_event(req, ret);
        io_put_req_find_next(req, nxt);
        return 0;
@@ -2017,55 +2284,45 @@ static int io_connect(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 #endif
 }
 
-static inline void io_poll_remove_req(struct io_kiocb *req)
-{
-       if (!RB_EMPTY_NODE(&req->rb_node)) {
-               rb_erase(&req->rb_node, &req->ctx->cancel_tree);
-               RB_CLEAR_NODE(&req->rb_node);
-       }
-}
-
 static void io_poll_remove_one(struct io_kiocb *req)
 {
        struct io_poll_iocb *poll = &req->poll;
 
        spin_lock(&poll->head->lock);
        WRITE_ONCE(poll->canceled, true);
-       if (!list_empty(&poll->wait->entry)) {
-               list_del_init(&poll->wait->entry);
+       if (!list_empty(&poll->wait.entry)) {
+               list_del_init(&poll->wait.entry);
                io_queue_async_work(req);
        }
        spin_unlock(&poll->head->lock);
-       io_poll_remove_req(req);
+       hash_del(&req->hash_node);
 }
 
 static void io_poll_remove_all(struct io_ring_ctx *ctx)
 {
-       struct rb_node *node;
+       struct hlist_node *tmp;
        struct io_kiocb *req;
+       int i;
 
        spin_lock_irq(&ctx->completion_lock);
-       while ((node = rb_first(&ctx->cancel_tree)) != NULL) {
-               req = rb_entry(node, struct io_kiocb, rb_node);
-               io_poll_remove_one(req);
+       for (i = 0; i < (1U << ctx->cancel_hash_bits); i++) {
+               struct hlist_head *list;
+
+               list = &ctx->cancel_hash[i];
+               hlist_for_each_entry_safe(req, tmp, list, hash_node)
+                       io_poll_remove_one(req);
        }
        spin_unlock_irq(&ctx->completion_lock);
 }
 
 static int io_poll_cancel(struct io_ring_ctx *ctx, __u64 sqe_addr)
 {
-       struct rb_node *p, *parent = NULL;
+       struct hlist_head *list;
        struct io_kiocb *req;
 
-       p = ctx->cancel_tree.rb_node;
-       while (p) {
-               parent = p;
-               req = rb_entry(parent, struct io_kiocb, rb_node);
-               if (sqe_addr < req->user_data) {
-                       p = p->rb_left;
-               } else if (sqe_addr > req->user_data) {
-                       p = p->rb_right;
-               } else {
+       list = &ctx->cancel_hash[hash_long(sqe_addr, ctx->cancel_hash_bits)];
+       hlist_for_each_entry(req, list, hash_node) {
+               if (sqe_addr == req->user_data) {
                        io_poll_remove_one(req);
                        return 0;
                }
@@ -2094,8 +2351,8 @@ static int io_poll_remove(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        spin_unlock_irq(&ctx->completion_lock);
 
        io_cqring_add_event(req, ret);
-       if (ret < 0 && (req->flags & REQ_F_LINK))
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_put_req(req);
        return 0;
 }
@@ -2105,7 +2362,6 @@ static void io_poll_complete(struct io_kiocb *req, __poll_t mask, int error)
        struct io_ring_ctx *ctx = req->ctx;
 
        req->poll.done = true;
-       kfree(req->poll.wait);
        if (error)
                io_cqring_fill_event(req, error);
        else
@@ -2143,18 +2399,18 @@ static void io_poll_complete_work(struct io_wq_work **workptr)
         */
        spin_lock_irq(&ctx->completion_lock);
        if (!mask && ret != -ECANCELED) {
-               add_wait_queue(poll->head, poll->wait);
+               add_wait_queue(poll->head, &poll->wait);
                spin_unlock_irq(&ctx->completion_lock);
                return;
        }
-       io_poll_remove_req(req);
+       hash_del(&req->hash_node);
        io_poll_complete(req, mask, ret);
        spin_unlock_irq(&ctx->completion_lock);
 
        io_cqring_ev_posted(ctx);
 
-       if (ret < 0 && req->flags & REQ_F_LINK)
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_put_req_find_next(req, &nxt);
        if (nxt)
                *workptr = &nxt->work;
@@ -2173,7 +2429,7 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
        if (mask && !(mask & poll->events))
                return 0;
 
-       list_del_init(&poll->wait->entry);
+       list_del_init(&poll->wait.entry);
 
        /*
         * Run completion inline if we can. We're using trylock here because
@@ -2182,7 +2438,7 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
         * for finalizing the request, mark us as having grabbed that already.
         */
        if (mask && spin_trylock_irqsave(&ctx->completion_lock, flags)) {
-               io_poll_remove_req(req);
+               hash_del(&req->hash_node);
                io_poll_complete(req, mask, 0);
                req->flags |= REQ_F_COMP_LOCKED;
                io_put_req(req);
@@ -2214,26 +2470,16 @@ static void io_poll_queue_proc(struct file *file, struct wait_queue_head *head,
 
        pt->error = 0;
        pt->req->poll.head = head;
-       add_wait_queue(head, pt->req->poll.wait);
+       add_wait_queue(head, &pt->req->poll.wait);
 }
 
 static void io_poll_req_insert(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
-       struct rb_node **p = &ctx->cancel_tree.rb_node;
-       struct rb_node *parent = NULL;
-       struct io_kiocb *tmp;
-
-       while (*p) {
-               parent = *p;
-               tmp = rb_entry(parent, struct io_kiocb, rb_node);
-               if (req->user_data < tmp->user_data)
-                       p = &(*p)->rb_left;
-               else
-                       p = &(*p)->rb_right;
-       }
-       rb_link_node(&req->rb_node, parent, p);
-       rb_insert_color(&req->rb_node, &ctx->cancel_tree);
+       struct hlist_head *list;
+
+       list = &ctx->cancel_hash[hash_long(req->user_data, ctx->cancel_hash_bits)];
+       hlist_add_head(&req->hash_node, list);
 }
 
 static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe,
@@ -2253,15 +2499,11 @@ static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        if (!poll->file)
                return -EBADF;
 
-       poll->wait = kmalloc(sizeof(*poll->wait), GFP_KERNEL);
-       if (!poll->wait)
-               return -ENOMEM;
-
-       req->sqe = NULL;
+       req->io = NULL;
        INIT_IO_WORK(&req->work, io_poll_complete_work);
        events = READ_ONCE(sqe->poll_events);
        poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP;
-       RB_CLEAR_NODE(&req->rb_node);
+       INIT_HLIST_NODE(&req->hash_node);
 
        poll->head = NULL;
        poll->done = false;
@@ -2273,9 +2515,9 @@ static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        ipt.error = -EINVAL; /* same as no support for IOCB_CMD_POLL */
 
        /* initialized the list so that we can do list_empty checks */
-       INIT_LIST_HEAD(&poll->wait->entry);
-       init_waitqueue_func_entry(poll->wait, io_poll_wake);
-       poll->wait->private = poll;
+       INIT_LIST_HEAD(&poll->wait.entry);
+       init_waitqueue_func_entry(&poll->wait, io_poll_wake);
+       poll->wait.private = poll;
 
        INIT_LIST_HEAD(&req->list);
 
@@ -2284,14 +2526,14 @@ static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        spin_lock_irq(&ctx->completion_lock);
        if (likely(poll->head)) {
                spin_lock(&poll->head->lock);
-               if (unlikely(list_empty(&poll->wait->entry))) {
+               if (unlikely(list_empty(&poll->wait.entry))) {
                        if (ipt.error)
                                cancel = true;
                        ipt.error = 0;
                        mask = 0;
                }
                if (mask || ipt.error)
-                       list_del_init(&poll->wait->entry);
+                       list_del_init(&poll->wait.entry);
                else if (cancel)
                        WRITE_ONCE(poll->canceled, true);
                else if (!poll->done) /* actually waiting for an event */
@@ -2346,8 +2588,7 @@ static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer)
        spin_unlock_irqrestore(&ctx->completion_lock, flags);
 
        io_cqring_ev_posted(ctx);
-       if (req->flags & REQ_F_LINK)
-               req->flags |= REQ_F_FAIL_LINK;
+       req_set_fail_links(req);
        io_put_req(req);
        return HRTIMER_NORESTART;
 }
@@ -2368,12 +2609,11 @@ static int io_timeout_cancel(struct io_ring_ctx *ctx, __u64 user_data)
        if (ret == -ENOENT)
                return ret;
 
-       ret = hrtimer_try_to_cancel(&req->timeout.data->timer);
+       ret = hrtimer_try_to_cancel(&req->io->timeout.timer);
        if (ret == -1)
                return -EALREADY;
 
-       if (req->flags & REQ_F_LINK)
-               req->flags |= REQ_F_FAIL_LINK;
+       req_set_fail_links(req);
        io_cqring_fill_event(req, -ECANCELED);
        io_put_req(req);
        return 0;
@@ -2404,13 +2644,14 @@ static int io_timeout_remove(struct io_kiocb *req,
        io_commit_cqring(ctx);
        spin_unlock_irq(&ctx->completion_lock);
        io_cqring_ev_posted(ctx);
-       if (ret < 0 && req->flags & REQ_F_LINK)
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_put_req(req);
        return 0;
 }
 
-static int io_timeout_setup(struct io_kiocb *req)
+static int io_timeout_prep(struct io_kiocb *req, struct io_async_ctx *io,
+                          bool is_timeout_link)
 {
        const struct io_uring_sqe *sqe = req->sqe;
        struct io_timeout_data *data;
@@ -2420,15 +2661,14 @@ static int io_timeout_setup(struct io_kiocb *req)
                return -EINVAL;
        if (sqe->ioprio || sqe->buf_index || sqe->len != 1)
                return -EINVAL;
+       if (sqe->off && is_timeout_link)
+               return -EINVAL;
        flags = READ_ONCE(sqe->timeout_flags);
        if (flags & ~IORING_TIMEOUT_ABS)
                return -EINVAL;
 
-       data = kzalloc(sizeof(struct io_timeout_data), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
+       data = &io->timeout;
        data->req = req;
-       req->timeout.data = data;
        req->flags |= REQ_F_TIMEOUT;
 
        if (get_timespec64(&data->ts, u64_to_user_ptr(sqe->addr)))
@@ -2440,6 +2680,7 @@ static int io_timeout_setup(struct io_kiocb *req)
                data->mode = HRTIMER_MODE_REL;
 
        hrtimer_init(&data->timer, CLOCK_MONOTONIC, data->mode);
+       req->io = io;
        return 0;
 }
 
@@ -2448,16 +2689,24 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        unsigned count;
        struct io_ring_ctx *ctx = req->ctx;
        struct io_timeout_data *data;
+       struct io_async_ctx *io;
        struct list_head *entry;
        unsigned span = 0;
-       int ret;
 
-       ret = io_timeout_setup(req);
-       /* common setup allows flags (like links) set, we don't */
-       if (!ret && sqe->flags)
-               ret = -EINVAL;
-       if (ret)
-               return ret;
+       io = req->io;
+       if (!io) {
+               int ret;
+
+               io = kmalloc(sizeof(*io), GFP_KERNEL);
+               if (!io)
+                       return -ENOMEM;
+               ret = io_timeout_prep(req, io, false);
+               if (ret) {
+                       kfree(io);
+                       return ret;
+               }
+       }
+       data = &req->io->timeout;
 
        /*
         * sqe->off holds how many events that need to occur for this
@@ -2473,7 +2722,7 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        }
 
        req->sequence = ctx->cached_sq_head + count - 1;
-       req->timeout.data->seq_offset = count;
+       data->seq_offset = count;
 
        /*
         * Insertion sort, ensuring the first entry in the list is always
@@ -2484,7 +2733,7 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
                struct io_kiocb *nxt = list_entry(entry, struct io_kiocb, list);
                unsigned nxt_sq_head;
                long long tmp, tmp_nxt;
-               u32 nxt_offset = nxt->timeout.data->seq_offset;
+               u32 nxt_offset = nxt->io->timeout.seq_offset;
 
                if (nxt->flags & REQ_F_TIMEOUT_NOSEQ)
                        continue;
@@ -2517,7 +2766,6 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        req->sequence -= span;
 add:
        list_add(&req->list, entry);
-       data = req->timeout.data;
        data->timer.function = io_timeout_fn;
        hrtimer_start(&data->timer, timespec64_to_ktime(data->ts), data->mode);
        spin_unlock_irq(&ctx->completion_lock);
@@ -2578,8 +2826,8 @@ done:
        spin_unlock_irqrestore(&ctx->completion_lock, flags);
        io_cqring_ev_posted(ctx);
 
-       if (ret < 0 && (req->flags & REQ_F_LINK))
-               req->flags |= REQ_F_FAIL_LINK;
+       if (ret < 0)
+               req_set_fail_links(req);
        io_put_req_find_next(req, nxt);
 }
 
@@ -2598,30 +2846,76 @@ static int io_async_cancel(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        return 0;
 }
 
+static int io_req_defer_prep(struct io_kiocb *req, struct io_async_ctx *io)
+{
+       struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
+       struct iov_iter iter;
+       ssize_t ret;
+
+       memcpy(&io->sqe, req->sqe, sizeof(io->sqe));
+       req->sqe = &io->sqe;
+
+       switch (io->sqe.opcode) {
+       case IORING_OP_READV:
+       case IORING_OP_READ_FIXED:
+               ret = io_read_prep(req, &iovec, &iter, true);
+               break;
+       case IORING_OP_WRITEV:
+       case IORING_OP_WRITE_FIXED:
+               ret = io_write_prep(req, &iovec, &iter, true);
+               break;
+       case IORING_OP_SENDMSG:
+               ret = io_sendmsg_prep(req, io);
+               break;
+       case IORING_OP_RECVMSG:
+               ret = io_recvmsg_prep(req, io);
+               break;
+       case IORING_OP_CONNECT:
+               ret = io_connect_prep(req, io);
+               break;
+       case IORING_OP_TIMEOUT:
+               return io_timeout_prep(req, io, false);
+       case IORING_OP_LINK_TIMEOUT:
+               return io_timeout_prep(req, io, true);
+       default:
+               req->io = io;
+               return 0;
+       }
+
+       if (ret < 0)
+               return ret;
+
+       req->io = io;
+       io_req_map_io(req, ret, iovec, inline_vecs, &iter);
+       return 0;
+}
+
 static int io_req_defer(struct io_kiocb *req)
 {
-       struct io_uring_sqe *sqe_copy;
        struct io_ring_ctx *ctx = req->ctx;
+       struct io_async_ctx *io;
+       int ret;
 
        /* Still need defer if there is pending req in defer list. */
        if (!req_need_defer(req) && list_empty(&ctx->defer_list))
                return 0;
 
-       sqe_copy = kmalloc(sizeof(*sqe_copy), GFP_KERNEL);
-       if (!sqe_copy)
+       io = kmalloc(sizeof(*io), GFP_KERNEL);
+       if (!io)
                return -EAGAIN;
 
+       ret = io_req_defer_prep(req, io);
+       if (ret < 0) {
+               kfree(io);
+               return ret;
+       }
+
        spin_lock_irq(&ctx->completion_lock);
        if (!req_need_defer(req) && list_empty(&ctx->defer_list)) {
                spin_unlock_irq(&ctx->completion_lock);
-               kfree(sqe_copy);
                return 0;
        }
 
-       memcpy(sqe_copy, req->sqe, sizeof(*sqe_copy));
-       req->flags |= REQ_F_FREE_SQE;
-       req->sqe = sqe_copy;
-
        trace_io_uring_defer(ctx, req, req->user_data);
        list_add_tail(&req->list, &ctx->defer_list);
        spin_unlock_irq(&ctx->completion_lock);
@@ -2701,12 +2995,7 @@ static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt,
                if (req->result == -EAGAIN)
                        return -EAGAIN;
 
-               /* workqueue context doesn't hold uring_lock, grab it now */
-               if (req->in_async)
-                       mutex_lock(&ctx->uring_lock);
                io_iopoll_req_issued(req);
-               if (req->in_async)
-                       mutex_unlock(&ctx->uring_lock);
        }
 
        return 0;
@@ -2754,8 +3043,7 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
        io_put_req(req);
 
        if (ret) {
-               if (req->flags & REQ_F_LINK)
-                       req->flags |= REQ_F_FAIL_LINK;
+               req_set_fail_links(req);
                io_cqring_add_event(req, ret);
                io_put_req(req);
        }
@@ -2774,7 +3062,12 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
        }
 }
 
-static bool io_op_needs_file(const struct io_uring_sqe *sqe)
+static bool io_req_op_valid(int op)
+{
+       return op >= IORING_OP_NOP && op < IORING_OP_LAST;
+}
+
+static int io_op_needs_file(const struct io_uring_sqe *sqe)
 {
        int op = READ_ONCE(sqe->opcode);
 
@@ -2785,9 +3078,11 @@ static bool io_op_needs_file(const struct io_uring_sqe *sqe)
        case IORING_OP_TIMEOUT_REMOVE:
        case IORING_OP_ASYNC_CANCEL:
        case IORING_OP_LINK_TIMEOUT:
-               return false;
+               return 0;
        default:
-               return true;
+               if (io_req_op_valid(op))
+                       return 1;
+               return -EINVAL;
        }
 }
 
@@ -2804,7 +3099,7 @@ static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
        unsigned flags;
-       int fd;
+       int fd, ret;
 
        flags = READ_ONCE(req->sqe->flags);
        fd = READ_ONCE(req->sqe->fd);
@@ -2812,8 +3107,9 @@ static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req)
        if (flags & IOSQE_IO_DRAIN)
                req->flags |= REQ_F_IO_DRAIN;
 
-       if (!io_op_needs_file(req->sqe))
-               return 0;
+       ret = io_op_needs_file(req->sqe);
+       if (ret <= 0)
+               return ret;
 
        if (flags & IOSQE_FIXED_FILE) {
                if (unlikely(!ctx->file_table ||
@@ -2876,10 +3172,11 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
         * We don't expect the list to be empty, that will only happen if we
         * race with the completion of the linked work.
         */
-       if (!list_empty(&req->list)) {
-               prev = list_entry(req->list.prev, struct io_kiocb, link_list);
+       if (!list_empty(&req->link_list)) {
+               prev = list_entry(req->link_list.prev, struct io_kiocb,
+                                 link_list);
                if (refcount_inc_not_zero(&prev->refs)) {
-                       list_del_init(&req->list);
+                       list_del_init(&req->link_list);
                        prev->flags &= ~REQ_F_LINK_TIMEOUT;
                } else
                        prev = NULL;
@@ -2888,8 +3185,7 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
        spin_unlock_irqrestore(&ctx->completion_lock, flags);
 
        if (prev) {
-               if (prev->flags & REQ_F_LINK)
-                       prev->flags |= REQ_F_FAIL_LINK;
+               req_set_fail_links(prev);
                io_async_find_and_cancel(ctx, req, prev->user_data, NULL,
                                                -ETIME);
                io_put_req(prev);
@@ -2909,8 +3205,8 @@ static void io_queue_linked_timeout(struct io_kiocb *req)
         * we got a chance to setup the timer
         */
        spin_lock_irq(&ctx->completion_lock);
-       if (!list_empty(&req->list)) {
-               struct io_timeout_data *data = req->timeout.data;
+       if (!list_empty(&req->link_list)) {
+               struct io_timeout_data *data = &req->io->timeout;
 
                data->timer.function = io_link_timeout_fn;
                hrtimer_start(&data->timer, timespec64_to_ktime(data->ts),
@@ -2929,7 +3225,8 @@ static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req)
        if (!(req->flags & REQ_F_LINK))
                return NULL;
 
-       nxt = list_first_entry_or_null(&req->link_list, struct io_kiocb, list);
+       nxt = list_first_entry_or_null(&req->link_list, struct io_kiocb,
+                                       link_list);
        if (!nxt || nxt->sqe->opcode != IORING_OP_LINK_TIMEOUT)
                return NULL;
 
@@ -2939,13 +3236,14 @@ static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req)
 
 static void __io_queue_sqe(struct io_kiocb *req)
 {
-       struct io_kiocb *linked_timeout = io_prep_linked_timeout(req);
+       struct io_kiocb *linked_timeout;
        struct io_kiocb *nxt = NULL;
        int ret;
 
+again:
+       linked_timeout = io_prep_linked_timeout(req);
+
        ret = io_issue_sqe(req, &nxt, true);
-       if (nxt)
-               io_queue_async_work(nxt);
 
        /*
         * We async punt it if the file wasn't marked NOWAIT, or if the file
@@ -2953,15 +3251,6 @@ static void __io_queue_sqe(struct io_kiocb *req)
         */
        if (ret == -EAGAIN && (!(req->flags & REQ_F_NOWAIT) ||
            (req->flags & REQ_F_MUST_PUNT))) {
-               struct io_uring_sqe *sqe_copy;
-
-               sqe_copy = kmemdup(req->sqe, sizeof(*sqe_copy), GFP_KERNEL);
-               if (!sqe_copy)
-                       goto err;
-
-               req->sqe = sqe_copy;
-               req->flags |= REQ_F_FREE_SQE;
-
                if (req->work.flags & IO_WQ_WORK_NEEDS_FILES) {
                        ret = io_grab_files(req);
                        if (ret)
@@ -2973,7 +3262,7 @@ static void __io_queue_sqe(struct io_kiocb *req)
                 * submit reference when the iocb is actually submitted.
                 */
                io_queue_async_work(req);
-               return;
+               goto done_req;
        }
 
 err:
@@ -2990,10 +3279,15 @@ err:
        /* and drop final reference, if we failed */
        if (ret) {
                io_cqring_add_event(req, ret);
-               if (req->flags & REQ_F_LINK)
-                       req->flags |= REQ_F_FAIL_LINK;
+               req_set_fail_links(req);
                io_put_req(req);
        }
+done_req:
+       if (nxt) {
+               req = nxt;
+               nxt = NULL;
+               goto again;
+       }
 }
 
 static void io_queue_sqe(struct io_kiocb *req)
@@ -3010,8 +3304,7 @@ static void io_queue_sqe(struct io_kiocb *req)
        if (ret) {
                if (ret != -EIOCBQUEUED) {
                        io_cqring_add_event(req, ret);
-                       if (req->flags & REQ_F_LINK)
-                               req->flags |= REQ_F_FAIL_LINK;
+                       req_set_fail_links(req);
                        io_double_put_req(req);
                }
        } else
@@ -3027,10 +3320,10 @@ static inline void io_queue_link_head(struct io_kiocb *req)
                io_queue_sqe(req);
 }
 
+#define SQE_VALID_FLAGS        (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \
+                               IOSQE_IO_HARDLINK)
 
-#define SQE_VALID_FLAGS        (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK)
-
-static void io_submit_sqe(struct io_kiocb *req, struct io_submit_state *state,
+static bool io_submit_sqe(struct io_kiocb *req, struct io_submit_state *state,
                          struct io_kiocb **link)
 {
        struct io_ring_ctx *ctx = req->ctx;
@@ -3049,7 +3342,7 @@ static void io_submit_sqe(struct io_kiocb *req, struct io_submit_state *state,
 err_req:
                io_cqring_add_event(req, ret);
                io_double_put_req(req);
-               return;
+               return false;
        }
 
        /*
@@ -3061,40 +3354,41 @@ err_req:
         */
        if (*link) {
                struct io_kiocb *prev = *link;
-               struct io_uring_sqe *sqe_copy;
+               struct io_async_ctx *io;
 
                if (req->sqe->flags & IOSQE_IO_DRAIN)
                        (*link)->flags |= REQ_F_DRAIN_LINK | REQ_F_IO_DRAIN;
 
-               if (READ_ONCE(req->sqe->opcode) == IORING_OP_LINK_TIMEOUT) {
-                       ret = io_timeout_setup(req);
-                       /* common setup allows offset being set, we don't */
-                       if (!ret && req->sqe->off)
-                               ret = -EINVAL;
-                       if (ret) {
-                               prev->flags |= REQ_F_FAIL_LINK;
-                               goto err_req;
-                       }
-               }
+               if (req->sqe->flags & IOSQE_IO_HARDLINK)
+                       req->flags |= REQ_F_HARDLINK;
 
-               sqe_copy = kmemdup(req->sqe, sizeof(*sqe_copy), GFP_KERNEL);
-               if (!sqe_copy) {
+               io = kmalloc(sizeof(*io), GFP_KERNEL);
+               if (!io) {
                        ret = -EAGAIN;
                        goto err_req;
                }
 
-               req->sqe = sqe_copy;
-               req->flags |= REQ_F_FREE_SQE;
+               ret = io_req_defer_prep(req, io);
+               if (ret) {
+                       kfree(io);
+                       /* fail even hard links since we don't submit */
+                       prev->flags |= REQ_F_FAIL_LINK;
+                       goto err_req;
+               }
                trace_io_uring_link(ctx, req, prev);
-               list_add_tail(&req->list, &prev->link_list);
-       } else if (req->sqe->flags & IOSQE_IO_LINK) {
+               list_add_tail(&req->link_list, &prev->link_list);
+       } else if (req->sqe->flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) {
                req->flags |= REQ_F_LINK;
+               if (req->sqe->flags & IOSQE_IO_HARDLINK)
+                       req->flags |= REQ_F_HARDLINK;
 
                INIT_LIST_HEAD(&req->link_list);
                *link = req;
        } else {
                io_queue_sqe(req);
        }
+
+       return true;
 }
 
 /*
@@ -3113,7 +3407,7 @@ static void io_submit_state_end(struct io_submit_state *state)
  * Start submission side cache.
  */
 static void io_submit_state_start(struct io_submit_state *state,
-                                 struct io_ring_ctx *ctx, unsigned max_ios)
+                                 unsigned int max_ios)
 {
        blk_start_plug(&state->plug);
        state->free_reqs = 0;
@@ -3197,7 +3491,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
                return -EBUSY;
 
        if (nr > IO_PLUG_THRESHOLD) {
-               io_submit_state_start(&state, ctx, nr);
+               io_submit_state_start(&state, nr);
                statep = &state;
        }
 
@@ -3224,6 +3518,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
                        }
                }
 
+               submitted++;
                sqe_flags = req->sqe->flags;
 
                req->ring_file = ring_file;
@@ -3233,9 +3528,8 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
                req->needs_fixed_file = async;
                trace_io_uring_submit_sqe(ctx, req->sqe->user_data,
                                          true, async);
-               io_submit_sqe(req, statep, &link);
-               submitted++;
-
+               if (!io_submit_sqe(req, statep, &link))
+                       break;
                /*
                 * If previous wasn't linked and we have a linked command,
                 * that's the end of the chain. Submit the previous link.
@@ -3369,7 +3663,9 @@ static int io_sq_thread(void *data)
                }
 
                to_submit = min(to_submit, ctx->sq_entries);
+               mutex_lock(&ctx->uring_lock);
                ret = io_submit_sqes(ctx, to_submit, NULL, -1, &cur_mm, true);
+               mutex_unlock(&ctx->uring_lock);
                if (ret > 0)
                        inflight += ret;
        }
@@ -4363,6 +4659,7 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
        free_uid(ctx->user);
        put_cred(ctx->creds);
        kfree(ctx->completions);
+       kfree(ctx->cancel_hash);
        kmem_cache_free(req_cachep, ctx->fallback_req);
        kfree(ctx);
 }
@@ -4759,7 +5056,7 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
        ctx->compat = in_compat_syscall();
        ctx->account_mem = account_mem;
        ctx->user = user;
-       ctx->creds = prepare_creds();
+       ctx->creds = get_current_cred();
 
        ret = io_allocate_scq_urings(ctx, p);
        if (ret)
@@ -4794,7 +5091,8 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
        if (ret < 0)
                goto err;
 
-       p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP;
+       p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP |
+                       IORING_FEAT_SUBMIT_STABLE;
        trace_io_uring_create(ret, ctx, p->sq_entries, p->cq_entries, p->flags);
        return ret;
 err:
index d33c7bc..828444e 100644 (file)
@@ -28,6 +28,7 @@
 struct iomap_page {
        atomic_t                read_count;
        atomic_t                write_count;
+       spinlock_t              uptodate_lock;
        DECLARE_BITMAP(uptodate, PAGE_SIZE / 512);
 };
 
@@ -51,6 +52,7 @@ iomap_page_create(struct inode *inode, struct page *page)
        iop = kmalloc(sizeof(*iop), GFP_NOFS | __GFP_NOFAIL);
        atomic_set(&iop->read_count, 0);
        atomic_set(&iop->write_count, 0);
+       spin_lock_init(&iop->uptodate_lock);
        bitmap_zero(iop->uptodate, PAGE_SIZE / SECTOR_SIZE);
 
        /*
@@ -139,25 +141,38 @@ iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop,
 }
 
 static void
-iomap_set_range_uptodate(struct page *page, unsigned off, unsigned len)
+iomap_iop_set_range_uptodate(struct page *page, unsigned off, unsigned len)
 {
        struct iomap_page *iop = to_iomap_page(page);
        struct inode *inode = page->mapping->host;
        unsigned first = off >> inode->i_blkbits;
        unsigned last = (off + len - 1) >> inode->i_blkbits;
-       unsigned int i;
        bool uptodate = true;
+       unsigned long flags;
+       unsigned int i;
 
-       if (iop) {
-               for (i = 0; i < PAGE_SIZE / i_blocksize(inode); i++) {
-                       if (i >= first && i <= last)
-                               set_bit(i, iop->uptodate);
-                       else if (!test_bit(i, iop->uptodate))
-                               uptodate = false;
-               }
+       spin_lock_irqsave(&iop->uptodate_lock, flags);
+       for (i = 0; i < PAGE_SIZE / i_blocksize(inode); i++) {
+               if (i >= first && i <= last)
+                       set_bit(i, iop->uptodate);
+               else if (!test_bit(i, iop->uptodate))
+                       uptodate = false;
        }
 
-       if (uptodate && !PageError(page))
+       if (uptodate)
+               SetPageUptodate(page);
+       spin_unlock_irqrestore(&iop->uptodate_lock, flags);
+}
+
+static void
+iomap_set_range_uptodate(struct page *page, unsigned off, unsigned len)
+{
+       if (PageError(page))
+               return;
+
+       if (page_has_private(page))
+               iomap_iop_set_range_uptodate(page, off, len);
+       else
                SetPageUptodate(page);
 }
 
@@ -1128,6 +1143,7 @@ iomap_finish_ioend(struct iomap_ioend *ioend, int error)
        struct bio *bio = &ioend->io_inline_bio;
        struct bio *last = ioend->io_bio, *next;
        u64 start = bio->bi_iter.bi_sector;
+       loff_t offset = ioend->io_offset;
        bool quiet = bio_flagged(bio, BIO_QUIET);
 
        for (bio = &ioend->io_inline_bio; bio; bio = next) {
@@ -1148,12 +1164,12 @@ iomap_finish_ioend(struct iomap_ioend *ioend, int error)
                        iomap_finish_page_writeback(inode, bv->bv_page, error);
                bio_put(bio);
        }
+       /* The ioend has been freed by bio_put() */
 
        if (unlikely(error && !quiet)) {
                printk_ratelimited(KERN_ERR
 "%s: writeback error on inode %lu, offset %lld, sector %llu",
-                       inode->i_sb->s_id, inode->i_ino, ioend->io_offset,
-                       start);
+                       inode->i_sb->s_id, inode->i_ino, offset, start);
        }
 }
 
index 4d31503..9dc7e7a 100644 (file)
@@ -223,7 +223,7 @@ struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
                        dput(dentry);
                        return ERR_PTR(-EINVAL);
                }
-               dtmp = lookup_one_len_unlocked(kntmp->name, dentry,
+               dtmp = lookup_positive_unlocked(kntmp->name, dentry,
                                               strlen(kntmp->name));
                dput(dentry);
                if (IS_ERR(dtmp))
index 7d46faf..0afb6d5 100644 (file)
@@ -464,7 +464,8 @@ nlm_bind_host(struct nlm_host *host)
                        .version        = host->h_version,
                        .authflavor     = RPC_AUTH_UNIX,
                        .flags          = (RPC_CLNT_CREATE_NOPING |
-                                          RPC_CLNT_CREATE_AUTOBIND),
+                                          RPC_CLNT_CREATE_AUTOBIND |
+                                          RPC_CLNT_CREATE_REUSEPORT),
                        .cred           = host->h_cred,
                };
 
index 2dda552..d6c91d1 100644 (file)
@@ -1210,25 +1210,25 @@ static int follow_automount(struct path *path, struct nameidata *nd,
  * - Flagged as automount point
  *
  * This may only be called in refwalk mode.
+ * On success path->dentry is known positive.
  *
  * Serialization is taken care of in namespace.c
  */
 static int follow_managed(struct path *path, struct nameidata *nd)
 {
        struct vfsmount *mnt = path->mnt; /* held by caller, must be left alone */
-       unsigned managed;
+       unsigned flags;
        bool need_mntput = false;
        int ret = 0;
 
        /* Given that we're not holding a lock here, we retain the value in a
         * local variable for each dentry as we look at it so that we don't see
         * the components of that value change under us */
-       while (managed = READ_ONCE(path->dentry->d_flags),
-              managed &= DCACHE_MANAGED_DENTRY,
-              unlikely(managed != 0)) {
+       while (flags = smp_load_acquire(&path->dentry->d_flags),
+              unlikely(flags & DCACHE_MANAGED_DENTRY)) {
                /* Allow the filesystem to manage the transit without i_mutex
                 * being held. */
-               if (managed & DCACHE_MANAGE_TRANSIT) {
+               if (flags & DCACHE_MANAGE_TRANSIT) {
                        BUG_ON(!path->dentry->d_op);
                        BUG_ON(!path->dentry->d_op->d_manage);
                        ret = path->dentry->d_op->d_manage(path, false);
@@ -1237,7 +1237,7 @@ static int follow_managed(struct path *path, struct nameidata *nd)
                }
 
                /* Transit to a mounted filesystem. */
-               if (managed & DCACHE_MOUNTED) {
+               if (flags & DCACHE_MOUNTED) {
                        struct vfsmount *mounted = lookup_mnt(path);
                        if (mounted) {
                                dput(path->dentry);
@@ -1256,7 +1256,7 @@ static int follow_managed(struct path *path, struct nameidata *nd)
                }
 
                /* Handle an automount point */
-               if (managed & DCACHE_NEED_AUTOMOUNT) {
+               if (flags & DCACHE_NEED_AUTOMOUNT) {
                        ret = follow_automount(path, nd, &need_mntput);
                        if (ret < 0)
                                break;
@@ -1269,10 +1269,12 @@ static int follow_managed(struct path *path, struct nameidata *nd)
 
        if (need_mntput && path->mnt == mnt)
                mntput(path->mnt);
-       if (ret == -EISDIR || !ret)
-               ret = 1;
        if (need_mntput)
                nd->flags |= LOOKUP_JUMPED;
+       if (ret == -EISDIR || !ret)
+               ret = 1;
+       if (ret > 0 && unlikely(d_flags_negative(flags)))
+               ret = -ENOENT;
        if (unlikely(ret < 0))
                path_put_conditional(path, nd);
        return ret;
@@ -1621,10 +1623,6 @@ static int lookup_fast(struct nameidata *nd,
                dput(dentry);
                return status;
        }
-       if (unlikely(d_is_negative(dentry))) {
-               dput(dentry);
-               return -ENOENT;
-       }
 
        path->mnt = mnt;
        path->dentry = dentry;
@@ -1811,11 +1809,6 @@ static int walk_component(struct nameidata *nd, int flags)
                if (unlikely(err < 0))
                        return err;
 
-               if (unlikely(d_is_negative(path.dentry))) {
-                       path_to_nameidata(&path, nd);
-                       return -ENOENT;
-               }
-
                seq = 0;        /* we are already out of RCU mode */
                inode = d_backing_inode(path.dentry);
        }
@@ -2568,6 +2561,26 @@ struct dentry *lookup_one_len_unlocked(const char *name,
 }
 EXPORT_SYMBOL(lookup_one_len_unlocked);
 
+/*
+ * Like lookup_one_len_unlocked(), except that it yields ERR_PTR(-ENOENT)
+ * on negatives.  Returns known positive or ERR_PTR(); that's what
+ * most of the users want.  Note that pinned negative with unlocked parent
+ * _can_ become positive at any time, so callers of lookup_one_len_unlocked()
+ * need to be very careful; pinned positives have ->d_inode stable, so
+ * this one avoids such problems.
+ */
+struct dentry *lookup_positive_unlocked(const char *name,
+                                      struct dentry *base, int len)
+{
+       struct dentry *ret = lookup_one_len_unlocked(name, base, len);
+       if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) {
+               dput(ret);
+               ret = ERR_PTR(-ENOENT);
+       }
+       return ret;
+}
+EXPORT_SYMBOL(lookup_positive_unlocked);
+
 #ifdef CONFIG_UNIX98_PTYS
 int path_pts(struct path *path)
 {
@@ -2662,7 +2675,7 @@ mountpoint_last(struct nameidata *nd)
                                return PTR_ERR(path.dentry);
                }
        }
-       if (d_is_negative(path.dentry)) {
+       if (d_flags_negative(smp_load_acquire(&path.dentry->d_flags))) {
                dput(path.dentry);
                return -ENOENT;
        }
@@ -3356,11 +3369,6 @@ static int do_last(struct nameidata *nd,
        if (unlikely(error < 0))
                return error;
 
-       if (unlikely(d_is_negative(path.dentry))) {
-               path_to_nameidata(&path, nd);
-               return -ENOENT;
-       }
-
        /*
         * create/update audit record if it already exists.
         */
index 2adfe7b..be601d3 100644 (file)
@@ -2356,7 +2356,7 @@ static struct file *open_detached_copy(struct path *path, bool recursive)
        return file;
 }
 
-SYSCALL_DEFINE3(open_tree, int, dfd, const char *, filename, unsigned, flags)
+SYSCALL_DEFINE3(open_tree, int, dfd, const char __user *, filename, unsigned, flags)
 {
        struct file *file;
        struct path path;
@@ -3325,8 +3325,8 @@ struct dentry *mount_subtree(struct vfsmount *m, const char *name)
 }
 EXPORT_SYMBOL(mount_subtree);
 
-int ksys_mount(const char __user *dev_name, const char __user *dir_name,
-              const char __user *type, unsigned long flags, void __user *data)
+SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
+               char __user *, type, unsigned long, flags, void __user *, data)
 {
        int ret;
        char *kernel_type;
@@ -3359,12 +3359,6 @@ out_type:
        return ret;
 }
 
-SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
-               char __user *, type, unsigned long, flags, void __user *, data)
-{
-       return ksys_mount(dev_name, dir_name, type, flags, data);
-}
-
 /*
  * Create a kernel mount representation for a new, prepared superblock
  * (specified by fs_fd) and attach to an open_tree-like file descriptor.
@@ -3514,8 +3508,8 @@ err_fsfd:
  * Note the flags value is a combination of MOVE_MOUNT_* flags.
  */
 SYSCALL_DEFINE5(move_mount,
-               int, from_dfd, const char *, from_pathname,
-               int, to_dfd, const char *, to_pathname,
+               int, from_dfd, const char __user *, from_pathname,
+               int, to_dfd, const char __user *, to_pathname,
                unsigned int, flags)
 {
        struct path from_path, to_path;
index 8f34daf..5493502 100644 (file)
@@ -72,8 +72,8 @@ struct cb_getattrres {
        uint32_t bitmap[2];
        uint64_t size;
        uint64_t change_attr;
-       struct timespec ctime;
-       struct timespec mtime;
+       struct timespec64 ctime;
+       struct timespec64 mtime;
 };
 
 struct cb_recallargs {
index f39924b..cd4c6bc 100644 (file)
@@ -26,7 +26,6 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
        struct cb_getattrargs *args = argp;
        struct cb_getattrres *res = resp;
        struct nfs_delegation *delegation;
-       struct nfs_inode *nfsi;
        struct inode *inode;
 
        res->status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
@@ -47,17 +46,16 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
                                -ntohl(res->status));
                goto out;
        }
-       nfsi = NFS_I(inode);
        rcu_read_lock();
-       delegation = rcu_dereference(nfsi->delegation);
+       delegation = nfs4_get_valid_delegation(inode);
        if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
                goto out_iput;
        res->size = i_size_read(inode);
        res->change_attr = delegation->change_attr;
        if (nfs_have_writebacks(inode))
                res->change_attr++;
-       res->ctime = timespec64_to_timespec(inode->i_ctime);
-       res->mtime = timespec64_to_timespec(inode->i_mtime);
+       res->ctime = inode->i_ctime;
+       res->mtime = inode->i_mtime;
        res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
                args->bitmap[0];
        res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
index 73a5a5e..03a20f5 100644 (file)
@@ -627,7 +627,7 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u
        return 0;
 }
 
-static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time)
+static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec64 *time)
 {
        __be32 *p;
 
@@ -639,14 +639,14 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti
        return 0;
 }
 
-static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
+static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
 {
        if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
                return 0;
        return encode_attr_time(xdr,time);
 }
 
-static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
+static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
 {
        if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY))
                return 0;
index 3083830..02110a3 100644 (file)
@@ -312,6 +312,12 @@ again:
                /* Match nfsv4 minorversion */
                if (clp->cl_minorversion != data->minorversion)
                        continue;
+
+               /* Match request for a dedicated DS */
+               if (test_bit(NFS_CS_DS, &data->init_flags) !=
+                   test_bit(NFS_CS_DS, &clp->cl_flags))
+                       continue;
+
                /* Match the full socket address */
                if (!rpc_cmp_addr_port(sap, clap))
                        /* Match all xprt_switch full socket addresses */
@@ -515,6 +521,10 @@ int nfs_create_rpc_client(struct nfs_client *clp,
                args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
        if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
                args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
+       if (test_bit(NFS_CS_NOPING, &clp->cl_flags))
+               args.flags |= RPC_CLNT_CREATE_NOPING;
+       if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags))
+               args.flags |= RPC_CLNT_CREATE_REUSEPORT;
 
        if (!IS_ERR(clp->cl_rpcclient))
                return 0;
@@ -662,6 +672,7 @@ static int nfs_init_server(struct nfs_server *server,
                .timeparms = &timeparms,
                .cred = server->cred,
                .nconnect = data->nfs_server.nconnect,
+               .init_flags = (1UL << NFS_CS_REUSEPORT),
        };
        struct nfs_client *clp;
        int error;
index af549d7..fe57b2b 100644 (file)
@@ -199,7 +199,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
        delegation = rcu_dereference(NFS_I(inode)->delegation);
        if (delegation != NULL) {
                spin_lock(&delegation->lock);
-               if (delegation->inode != NULL) {
+               if (nfs4_is_valid_delegation(delegation, 0)) {
                        nfs4_stateid_copy(&delegation->stateid, stateid);
                        delegation->type = type;
                        delegation->pagemod_limit = pagemod_limit;
@@ -229,7 +229,6 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
                                delegation->cred,
                                &delegation->stateid,
                                issync);
-       nfs_free_delegation(delegation);
        return res;
 }
 
@@ -298,7 +297,10 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi,
                return NULL;
 
        spin_lock(&delegation->lock);
-       set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
+       if (!delegation->inode) {
+               spin_unlock(&delegation->lock);
+               return NULL;
+       }
        list_del_rcu(&delegation->super_list);
        delegation->inode = NULL;
        rcu_assign_pointer(nfsi->delegation, NULL);
@@ -325,10 +327,12 @@ nfs_inode_detach_delegation(struct inode *inode)
        struct nfs_server *server = NFS_SERVER(inode);
        struct nfs_delegation *delegation;
 
-       delegation = nfs_start_delegation_return(nfsi);
-       if (delegation == NULL)
-               return NULL;
-       return nfs_detach_delegation(nfsi, delegation, server);
+       rcu_read_lock();
+       delegation = rcu_dereference(nfsi->delegation);
+       if (delegation != NULL)
+               delegation = nfs_detach_delegation(nfsi, delegation, server);
+       rcu_read_unlock();
+       return delegation;
 }
 
 static void
@@ -339,6 +343,7 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation,
                delegation->stateid.seqid = update->stateid.seqid;
                smp_wmb();
                delegation->type = update->type;
+               clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
        }
 }
 
@@ -379,14 +384,18 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
        spin_lock(&clp->cl_lock);
        old_delegation = rcu_dereference_protected(nfsi->delegation,
                                        lockdep_is_held(&clp->cl_lock));
-       if (old_delegation != NULL) {
-               /* Is this an update of the existing delegation? */
-               if (nfs4_stateid_match_other(&old_delegation->stateid,
-                                       &delegation->stateid)) {
-                       nfs_update_inplace_delegation(old_delegation,
-                                       delegation);
-                       goto out;
-               }
+       if (old_delegation == NULL)
+               goto add_new;
+       /* Is this an update of the existing delegation? */
+       if (nfs4_stateid_match_other(&old_delegation->stateid,
+                               &delegation->stateid)) {
+               spin_lock(&old_delegation->lock);
+               nfs_update_inplace_delegation(old_delegation,
+                               delegation);
+               spin_unlock(&old_delegation->lock);
+               goto out;
+       }
+       if (!test_bit(NFS_DELEGATION_REVOKED, &old_delegation->flags)) {
                /*
                 * Deal with broken servers that hand out two
                 * delegations for the same file.
@@ -405,11 +414,11 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
                if (test_and_set_bit(NFS_DELEGATION_RETURNING,
                                        &old_delegation->flags))
                        goto out;
-               freeme = nfs_detach_delegation_locked(nfsi,
-                               old_delegation, clp);
-               if (freeme == NULL)
-                       goto out;
        }
+       freeme = nfs_detach_delegation_locked(nfsi, old_delegation, clp);
+       if (freeme == NULL)
+               goto out;
+add_new:
        list_add_tail_rcu(&delegation->super_list, &server->delegations);
        rcu_assign_pointer(nfsi->delegation, delegation);
        delegation = NULL;
@@ -424,8 +433,10 @@ out:
        spin_unlock(&clp->cl_lock);
        if (delegation != NULL)
                nfs_free_delegation(delegation);
-       if (freeme != NULL)
+       if (freeme != NULL) {
                nfs_do_return_delegation(inode, freeme, 0);
+               nfs_free_delegation(freeme);
+       }
        return status;
 }
 
@@ -435,7 +446,6 @@ out:
 static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
 {
        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
-       struct nfs_inode *nfsi = NFS_I(inode);
        int err = 0;
 
        if (delegation == NULL)
@@ -457,8 +467,6 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
                nfs_abort_delegation_return(delegation, clp);
                goto out;
        }
-       if (!nfs_detach_delegation(nfsi, delegation, NFS_SERVER(inode)))
-               goto out;
 
        err = nfs_do_return_delegation(inode, delegation, issync);
 out:
@@ -469,8 +477,6 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
 {
        bool ret = false;
 
-       if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
-               goto out;
        if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
                ret = true;
        if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) {
@@ -482,7 +488,10 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
                        ret = true;
                spin_unlock(&delegation->lock);
        }
-out:
+       if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) ||
+           test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+               ret = false;
+
        return ret;
 }
 
@@ -585,19 +594,23 @@ restart:
 }
 
 /**
- * nfs_inode_return_delegation_noreclaim - return delegation, don't reclaim opens
+ * nfs_inode_evict_delegation - return delegation, don't reclaim opens
  * @inode: inode to process
  *
  * Does not protect against delegation reclaims, therefore really only safe
- * to be called from nfs4_clear_inode().
+ * to be called from nfs4_clear_inode(). Guaranteed to always free
+ * the delegation structure.
  */
-void nfs_inode_return_delegation_noreclaim(struct inode *inode)
+void nfs_inode_evict_delegation(struct inode *inode)
 {
        struct nfs_delegation *delegation;
 
        delegation = nfs_inode_detach_delegation(inode);
-       if (delegation != NULL)
+       if (delegation != NULL) {
+               set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags);
                nfs_do_return_delegation(inode, delegation, 1);
+               nfs_free_delegation(delegation);
+       }
 }
 
 /**
@@ -633,10 +646,18 @@ int nfs4_inode_return_delegation(struct inode *inode)
  */
 int nfs4_inode_make_writeable(struct inode *inode)
 {
-       if (!nfs4_has_session(NFS_SERVER(inode)->nfs_client) ||
-           !nfs4_check_delegation(inode, FMODE_WRITE))
-               return nfs4_inode_return_delegation(inode);
-       return 0;
+       struct nfs_delegation *delegation;
+
+       rcu_read_lock();
+       delegation = nfs4_get_valid_delegation(inode);
+       if (delegation == NULL ||
+           (nfs4_has_session(NFS_SERVER(inode)->nfs_client) &&
+            (delegation->type & FMODE_WRITE))) {
+               rcu_read_unlock();
+               return 0;
+       }
+       rcu_read_unlock();
+       return nfs4_inode_return_delegation(inode);
 }
 
 static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
@@ -744,10 +765,9 @@ static void nfs_mark_delegation_revoked(struct nfs_server *server,
 {
        set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
        delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
-       nfs_mark_return_delegation(server, delegation);
 }
 
-static bool nfs_revoke_delegation(struct inode *inode,
+static void nfs_revoke_delegation(struct inode *inode,
                const nfs4_stateid *stateid)
 {
        struct nfs_delegation *delegation;
@@ -761,29 +781,69 @@ static bool nfs_revoke_delegation(struct inode *inode,
        if (stateid == NULL) {
                nfs4_stateid_copy(&tmp, &delegation->stateid);
                stateid = &tmp;
-       } else if (!nfs4_stateid_match(stateid, &delegation->stateid))
-               goto out;
+       } else {
+               if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
+                       goto out;
+               spin_lock(&delegation->lock);
+               if (stateid->seqid) {
+                       if (nfs4_stateid_is_newer(&delegation->stateid, stateid)) {
+                               spin_unlock(&delegation->lock);
+                               goto out;
+                       }
+                       delegation->stateid.seqid = stateid->seqid;
+               }
+               spin_unlock(&delegation->lock);
+       }
        nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
        ret = true;
 out:
        rcu_read_unlock();
        if (ret)
                nfs_inode_find_state_and_recover(inode, stateid);
-       return ret;
 }
 
 void nfs_remove_bad_delegation(struct inode *inode,
                const nfs4_stateid *stateid)
 {
+       nfs_revoke_delegation(inode, stateid);
+}
+EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
+
+void nfs_delegation_mark_returned(struct inode *inode,
+               const nfs4_stateid *stateid)
+{
        struct nfs_delegation *delegation;
 
-       if (!nfs_revoke_delegation(inode, stateid))
+       if (!inode)
                return;
-       delegation = nfs_inode_detach_delegation(inode);
-       if (delegation)
-               nfs_free_delegation(delegation);
+
+       rcu_read_lock();
+       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       if (!delegation)
+               goto out_rcu_unlock;
+
+       spin_lock(&delegation->lock);
+       if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
+               goto out_spin_unlock;
+       if (stateid->seqid) {
+               /* If delegation->stateid is newer, dont mark as returned */
+               if (nfs4_stateid_is_newer(&delegation->stateid, stateid))
+                       goto out_clear_returning;
+               if (delegation->stateid.seqid != stateid->seqid)
+                       delegation->stateid.seqid = stateid->seqid;
+       }
+
+       nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
+
+out_clear_returning:
+       clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
+out_spin_unlock:
+       spin_unlock(&delegation->lock);
+out_rcu_unlock:
+       rcu_read_unlock();
+
+       nfs_inode_find_state_and_recover(inode, stateid);
 }
-EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
 
 /**
  * nfs_expire_unused_delegation_types
@@ -840,7 +900,7 @@ int nfs_async_inode_return_delegation(struct inode *inode,
        struct nfs_delegation *delegation;
 
        rcu_read_lock();
-       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       delegation = nfs4_get_valid_delegation(inode);
        if (delegation == NULL)
                goto out_enoent;
        if (stateid != NULL &&
@@ -866,6 +926,7 @@ nfs_delegation_find_inode_server(struct nfs_server *server,
        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
                spin_lock(&delegation->lock);
                if (delegation->inode != NULL &&
+                   !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
                    nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
                        freeme = igrab(delegation->inode);
                        if (freeme && nfs_sb_active(freeme->i_sb))
@@ -1140,7 +1201,8 @@ void nfs_inode_find_delegation_state_and_recover(struct inode *inode,
        rcu_read_lock();
        delegation = rcu_dereference(NFS_I(inode)->delegation);
        if (delegation &&
-           nfs4_stateid_match_other(&delegation->stateid, stateid)) {
+           nfs4_stateid_match_or_older(&delegation->stateid, stateid) &&
+           !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
                nfs_mark_test_expired_delegation(NFS_SERVER(inode), delegation);
                found = true;
        }
@@ -1189,7 +1251,9 @@ bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
        rcu_read_lock();
        delegation = rcu_dereference(NFS_I(inode)->delegation);
        if (delegation != NULL &&
-           nfs4_stateid_match_other(dst, &delegation->stateid)) {
+           nfs4_stateid_match_other(dst, &delegation->stateid) &&
+           nfs4_stateid_is_newer(&delegation->stateid, dst) &&
+           !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
                dst->seqid = delegation->stateid.seqid;
                ret = true;
        }
index 8b14d44..15d3484 100644 (file)
@@ -43,7 +43,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
                fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);
 int nfs4_inode_return_delegation(struct inode *inode);
 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
-void nfs_inode_return_delegation_noreclaim(struct inode *inode);
+void nfs_inode_evict_delegation(struct inode *inode);
 
 struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
 void nfs_server_return_all_delegations(struct nfs_server *);
@@ -53,6 +53,7 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp);
 int nfs_client_return_marked_delegations(struct nfs_client *clp);
 int nfs_delegations_present(struct nfs_client *clp);
 void nfs_remove_bad_delegation(struct inode *inode, const nfs4_stateid *stateid);
+void nfs_delegation_mark_returned(struct inode *inode, const nfs4_stateid *stateid);
 
 void nfs_delegation_mark_reclaim(struct nfs_client *clp);
 void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
index deecb67..3430d68 100644 (file)
@@ -105,6 +105,7 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
        ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, label, NULL);
        if (ret) {
                dprintk("%s: getattr failed %d\n", __func__, ret);
+               trace_nfs_fh_to_dentry(sb, server_fh, fattr->fileid, ret);
                dentry = ERR_PTR(ret);
                goto out_free_label;
        }
index 95dc905..8eb731d 100644 (file)
@@ -649,7 +649,7 @@ out:
 
 out_swapfile:
        printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
-       return -EBUSY;
+       return -ETXTBSY;
 }
 EXPORT_SYMBOL_GPL(nfs_file_write);
 
index 2a03bfe..b0b4b9f 100644 (file)
@@ -504,15 +504,15 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                nfsi->read_cache_jiffies = fattr->time_start;
                nfsi->attr_gencount = fattr->gencount;
                if (fattr->valid & NFS_ATTR_FATTR_ATIME)
-                       inode->i_atime = timespec_to_timespec64(fattr->atime);
+                       inode->i_atime = fattr->atime;
                else if (nfs_server_capable(inode, NFS_CAP_ATIME))
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
                if (fattr->valid & NFS_ATTR_FATTR_MTIME)
-                       inode->i_mtime = timespec_to_timespec64(fattr->mtime);
+                       inode->i_mtime = fattr->mtime;
                else if (nfs_server_capable(inode, NFS_CAP_MTIME))
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);
                if (fattr->valid & NFS_ATTR_FATTR_CTIME)
-                       inode->i_ctime = timespec_to_timespec64(fattr->ctime);
+                       inode->i_ctime = fattr->ctime;
                else if (nfs_server_capable(inode, NFS_CAP_CTIME))
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME);
                if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
@@ -698,7 +698,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
                if ((attr->ia_valid & ATTR_GID) != 0)
                        inode->i_gid = attr->ia_gid;
                if (fattr->valid & NFS_ATTR_FATTR_CTIME)
-                       inode->i_ctime = timespec_to_timespec64(fattr->ctime);
+                       inode->i_ctime = fattr->ctime;
                else
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE
                                        | NFS_INO_INVALID_CTIME);
@@ -709,14 +709,14 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
                NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_ATIME
                                | NFS_INO_INVALID_CTIME);
                if (fattr->valid & NFS_ATTR_FATTR_ATIME)
-                       inode->i_atime = timespec_to_timespec64(fattr->atime);
+                       inode->i_atime = fattr->atime;
                else if (attr->ia_valid & ATTR_ATIME_SET)
                        inode->i_atime = attr->ia_atime;
                else
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
 
                if (fattr->valid & NFS_ATTR_FATTR_CTIME)
-                       inode->i_ctime = timespec_to_timespec64(fattr->ctime);
+                       inode->i_ctime = fattr->ctime;
                else
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE
                                        | NFS_INO_INVALID_CTIME);
@@ -725,14 +725,14 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
                NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_MTIME
                                | NFS_INO_INVALID_CTIME);
                if (fattr->valid & NFS_ATTR_FATTR_MTIME)
-                       inode->i_mtime = timespec_to_timespec64(fattr->mtime);
+                       inode->i_mtime = fattr->mtime;
                else if (attr->ia_valid & ATTR_MTIME_SET)
                        inode->i_mtime = attr->ia_mtime;
                else
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);
 
                if (fattr->valid & NFS_ATTR_FATTR_CTIME)
-                       inode->i_ctime = timespec_to_timespec64(fattr->ctime);
+                       inode->i_ctime = fattr->ctime;
                else
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE
                                        | NFS_INO_INVALID_CTIME);
@@ -1351,7 +1351,7 @@ static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi)
 
 static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 {
-       struct timespec ts;
+       struct timespec64 ts;
 
        if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
                        && (fattr->valid & NFS_ATTR_FATTR_CHANGE)
@@ -1361,18 +1361,18 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
        }
        /* If we have atomic WCC data, we may update some attributes */
-       ts = timespec64_to_timespec(inode->i_ctime);
+       ts = inode->i_ctime;
        if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME)
                        && (fattr->valid & NFS_ATTR_FATTR_CTIME)
-                       && timespec_equal(&ts, &fattr->pre_ctime)) {
-               inode->i_ctime = timespec_to_timespec64(fattr->ctime);
+                       && timespec64_equal(&ts, &fattr->pre_ctime)) {
+               inode->i_ctime = fattr->ctime;
        }
 
-       ts = timespec64_to_timespec(inode->i_mtime);
+       ts = inode->i_mtime;
        if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME)
                        && (fattr->valid & NFS_ATTR_FATTR_MTIME)
-                       && timespec_equal(&ts, &fattr->pre_mtime)) {
-               inode->i_mtime = timespec_to_timespec64(fattr->mtime);
+                       && timespec64_equal(&ts, &fattr->pre_mtime)) {
+               inode->i_mtime = fattr->mtime;
                if (S_ISDIR(inode->i_mode))
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
        }
@@ -1398,7 +1398,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        struct nfs_inode *nfsi = NFS_I(inode);
        loff_t cur_size, new_isize;
        unsigned long invalid = 0;
-       struct timespec ts;
+       struct timespec64 ts;
 
        if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
                return 0;
@@ -1425,12 +1425,12 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
                        invalid |= NFS_INO_INVALID_CHANGE
                                | NFS_INO_REVAL_PAGECACHE;
 
-               ts = timespec64_to_timespec(inode->i_mtime);
-               if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&ts, &fattr->mtime))
+               ts = inode->i_mtime;
+               if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec64_equal(&ts, &fattr->mtime))
                        invalid |= NFS_INO_INVALID_MTIME;
 
-               ts = timespec64_to_timespec(inode->i_ctime);
-               if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec_equal(&ts, &fattr->ctime))
+               ts = inode->i_ctime;
+               if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec64_equal(&ts, &fattr->ctime))
                        invalid |= NFS_INO_INVALID_CTIME;
 
                if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
@@ -1460,8 +1460,8 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
                invalid |= NFS_INO_INVALID_OTHER;
 
-       ts = timespec64_to_timespec(inode->i_atime);
-       if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec_equal(&ts, &fattr->atime))
+       ts = inode->i_atime;
+       if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec64_equal(&ts, &fattr->atime))
                invalid |= NFS_INO_INVALID_ATIME;
 
        if (invalid != 0)
@@ -1733,12 +1733,12 @@ int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fa
        }
        if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
                        (fattr->valid & NFS_ATTR_FATTR_PRECTIME) == 0) {
-               fattr->pre_ctime = timespec64_to_timespec(inode->i_ctime);
+               fattr->pre_ctime = inode->i_ctime;
                fattr->valid |= NFS_ATTR_FATTR_PRECTIME;
        }
        if ((fattr->valid & NFS_ATTR_FATTR_MTIME) != 0 &&
                        (fattr->valid & NFS_ATTR_FATTR_PREMTIME) == 0) {
-               fattr->pre_mtime = timespec64_to_timespec(inode->i_mtime);
+               fattr->pre_mtime = inode->i_mtime;
                fattr->valid |= NFS_ATTR_FATTR_PREMTIME;
        }
        if ((fattr->valid & NFS_ATTR_FATTR_SIZE) != 0 &&
@@ -1899,7 +1899,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
        }
 
        if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
-               inode->i_mtime = timespec_to_timespec64(fattr->mtime);
+               inode->i_mtime = fattr->mtime;
        } else if (server->caps & NFS_CAP_MTIME) {
                nfsi->cache_validity |= save_cache_validity &
                                (NFS_INO_INVALID_MTIME
@@ -1908,7 +1908,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
        }
 
        if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
-               inode->i_ctime = timespec_to_timespec64(fattr->ctime);
+               inode->i_ctime = fattr->ctime;
        } else if (server->caps & NFS_CAP_CTIME) {
                nfsi->cache_validity |= save_cache_validity &
                                (NFS_INO_INVALID_CTIME
@@ -1946,7 +1946,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 
 
        if (fattr->valid & NFS_ATTR_FATTR_ATIME)
-               inode->i_atime = timespec_to_timespec64(fattr->atime);
+               inode->i_atime = fattr->atime;
        else if (server->caps & NFS_CAP_ATIME) {
                nfsi->cache_validity |= save_cache_validity &
                                (NFS_INO_INVALID_ATIME
index 447a3c1..24a65da 100644 (file)
@@ -713,7 +713,7 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
  * 1024*1024*1024.
  */
 static inline
-u64 nfs_timespec_to_change_attr(const struct timespec *ts)
+u64 nfs_timespec_to_change_attr(const struct timespec64 *ts)
 {
        return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
 }
index 9287eb6..5e0e9d2 100644 (file)
@@ -157,6 +157,9 @@ struct vfsmount *nfs_d_automount(struct path *path)
        if (IS_ERR(mnt))
                goto out;
 
+       if (nfs_mountpoint_expiry_timeout < 0)
+               goto out;
+
        mntget(mnt); /* prevent immediate expiration */
        mnt_set_expiry(mnt, &nfs_automount_list);
        schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
index cbc17a2..d94c7ab 100644 (file)
@@ -209,9 +209,9 @@ static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
  *             unsigned int useconds;
  *     };
  */
-static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
+static __be32 *xdr_encode_time(__be32 *p, const struct timespec64 *timep)
 {
-       *p++ = cpu_to_be32(timep->tv_sec);
+       *p++ = cpu_to_be32((u32)timep->tv_sec);
        if (timep->tv_nsec != 0)
                *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
        else
@@ -227,14 +227,14 @@ static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
  * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
  */
 static __be32 *xdr_encode_current_server_time(__be32 *p,
-                                             const struct timespec *timep)
+                                             const struct timespec64 *timep)
 {
        *p++ = cpu_to_be32(timep->tv_sec);
        *p++ = cpu_to_be32(1000000);
        return p;
 }
 
-static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
+static __be32 *xdr_decode_time(__be32 *p, struct timespec64 *timep)
 {
        timep->tv_sec = be32_to_cpup(p++);
        timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
@@ -339,7 +339,6 @@ static __be32 *xdr_time_not_set(__be32 *p)
 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
                struct user_namespace *userns)
 {
-       struct timespec ts;
        __be32 *p;
 
        p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
@@ -362,19 +361,15 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
                *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 
        if (attr->ia_valid & ATTR_ATIME_SET) {
-               ts = timespec64_to_timespec(attr->ia_atime);
-               p = xdr_encode_time(p, &ts);
+               p = xdr_encode_time(p, &attr->ia_atime);
        } else if (attr->ia_valid & ATTR_ATIME) {
-               ts = timespec64_to_timespec(attr->ia_atime);
-               p = xdr_encode_current_server_time(p, &ts);
+               p = xdr_encode_current_server_time(p, &attr->ia_atime);
        } else
                p = xdr_time_not_set(p);
        if (attr->ia_valid & ATTR_MTIME_SET) {
-               ts = timespec64_to_timespec(attr->ia_atime);
-               xdr_encode_time(p, &ts);
+               xdr_encode_time(p, &attr->ia_mtime);
        } else if (attr->ia_valid & ATTR_MTIME) {
-               ts = timespec64_to_timespec(attr->ia_mtime);
-               xdr_encode_current_server_time(p, &ts);
+               xdr_encode_current_server_time(p, &attr->ia_mtime);
        } else
                xdr_time_not_set(p);
 }
index 148ceb7..223904b 100644 (file)
@@ -106,7 +106,10 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
                cl_init.nconnect = mds_clp->cl_nconnect;
 
        if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
-               set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
+               __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
+
+       __set_bit(NFS_CS_NOPING, &cl_init.init_flags);
+       __set_bit(NFS_CS_DS, &cl_init.init_flags);
 
        /* Use the MDS nfs_client cl_ipaddr. */
        nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
index 6027678..927eb68 100644 (file)
@@ -456,14 +456,14 @@ static void zero_nfs_fh3(struct nfs_fh *fh)
  *             uint32  nseconds;
  *     };
  */
-static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
+static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec64 *timep)
 {
-       *p++ = cpu_to_be32(timep->tv_sec);
+       *p++ = cpu_to_be32((u32)timep->tv_sec);
        *p++ = cpu_to_be32(timep->tv_nsec);
        return p;
 }
 
-static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep)
+static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec64 *timep)
 {
        timep->tv_sec = be32_to_cpup(p++);
        timep->tv_nsec = be32_to_cpup(p++);
@@ -533,7 +533,6 @@ static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep)
 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,
                struct user_namespace *userns)
 {
-       struct timespec ts;
        u32 nbytes;
        __be32 *p;
 
@@ -583,10 +582,8 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,
                *p++ = xdr_zero;
 
        if (attr->ia_valid & ATTR_ATIME_SET) {
-               struct timespec ts;
                *p++ = xdr_two;
-               ts = timespec64_to_timespec(attr->ia_atime);
-               p = xdr_encode_nfstime3(p, &ts);
+               p = xdr_encode_nfstime3(p, &attr->ia_atime);
        } else if (attr->ia_valid & ATTR_ATIME) {
                *p++ = xdr_one;
        } else
@@ -594,8 +591,7 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,
 
        if (attr->ia_valid & ATTR_MTIME_SET) {
                *p++ = xdr_two;
-               ts = timespec64_to_timespec(attr->ia_mtime);
-               xdr_encode_nfstime3(p, &ts);
+               xdr_encode_nfstime3(p, &attr->ia_mtime);
        } else if (attr->ia_valid & ATTR_MTIME) {
                *p = xdr_one;
        } else
index 901cca7..c891af9 100644 (file)
 #define PNFS_LAYOUTSTATS_MAXDEV (4)
 
 /* nfs4.2proc.c */
+#ifdef CONFIG_NFS_V4_2
 int nfs42_proc_allocate(struct file *, loff_t, loff_t);
-ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t);
+ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t,
+                       struct nl4_server *, nfs4_stateid *, bool);
 int nfs42_proc_deallocate(struct file *, loff_t, loff_t);
 loff_t nfs42_proc_llseek(struct file *, loff_t, int);
 int nfs42_proc_layoutstats_generic(struct nfs_server *,
@@ -23,5 +25,16 @@ int nfs42_proc_clone(struct file *, struct file *, loff_t, loff_t, loff_t);
 int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg,
                           const struct nfs42_layout_error *errors,
                           size_t n);
+int nfs42_proc_copy_notify(struct file *, struct file *,
+                          struct nfs42_copy_notify_res *);
+static inline bool nfs42_files_from_same_server(struct file *in,
+                                               struct file *out)
+{
+       struct nfs_client *c_in = (NFS_SERVER(file_inode(in)))->nfs_client;
+       struct nfs_client *c_out = (NFS_SERVER(file_inode(out)))->nfs_client;
 
+       return nfs4_check_serverowner_major_id(c_in->cl_serverowner,
+                                              c_out->cl_serverowner);
+}
+#endif /* CONFIG_NFS_V4_2 */
 #endif /* __LINUX_FS_NFS_NFS4_2_H */
index 5196bfa..1fe83e0 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
  */
 #include <linux/fs.h>
+#include <linux/sunrpc/addr.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include "pnfs.h"
 #include "nfs4session.h"
 #include "internal.h"
+#include "delegation.h"
 
 #define NFSDBG_FACILITY NFSDBG_PROC
 static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std);
 
+static void nfs42_set_netaddr(struct file *filep, struct nfs42_netaddr *naddr)
+{
+       struct nfs_client *clp = (NFS_SERVER(file_inode(filep)))->nfs_client;
+       unsigned short port = 2049;
+
+       rcu_read_lock();
+       naddr->netid_len = scnprintf(naddr->netid,
+                                       sizeof(naddr->netid), "%s",
+                                       rpc_peeraddr2str(clp->cl_rpcclient,
+                                       RPC_DISPLAY_NETID));
+       naddr->addr_len = scnprintf(naddr->addr,
+                                       sizeof(naddr->addr),
+                                       "%s.%u.%u",
+                                       rpc_peeraddr2str(clp->cl_rpcclient,
+                                       RPC_DISPLAY_ADDR),
+                                       port >> 8, port & 255);
+       rcu_read_unlock();
+}
+
 static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
                struct nfs_lock_context *lock, loff_t offset, loff_t len)
 {
@@ -28,7 +49,7 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
                .falloc_fh      = NFS_FH(inode),
                .falloc_offset  = offset,
                .falloc_length  = len,
-               .falloc_bitmask = server->cache_consistency_bitmask,
+               .falloc_bitmask = nfs4_fattr_bitmap,
        };
        struct nfs42_falloc_res res = {
                .falloc_server  = server,
@@ -132,22 +153,26 @@ out_unlock:
 }
 
 static int handle_async_copy(struct nfs42_copy_res *res,
-                            struct nfs_server *server,
+                            struct nfs_server *dst_server,
+                            struct nfs_server *src_server,
                             struct file *src,
                             struct file *dst,
-                            nfs4_stateid *src_stateid)
+                            nfs4_stateid *src_stateid,
+                            bool *restart)
 {
        struct nfs4_copy_state *copy, *tmp_copy;
        int status = NFS4_OK;
        bool found_pending = false;
-       struct nfs_open_context *ctx = nfs_file_open_context(dst);
+       struct nfs_open_context *dst_ctx = nfs_file_open_context(dst);
+       struct nfs_open_context *src_ctx = nfs_file_open_context(src);
 
        copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
        if (!copy)
                return -ENOMEM;
 
-       spin_lock(&server->nfs_client->cl_lock);
-       list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids,
+       spin_lock(&dst_server->nfs_client->cl_lock);
+       list_for_each_entry(tmp_copy,
+                               &dst_server->nfs_client->pending_cb_stateids,
                                copies) {
                if (memcmp(&res->write_res.stateid, &tmp_copy->stateid,
                                NFS4_STATEID_SIZE))
@@ -157,7 +182,7 @@ static int handle_async_copy(struct nfs42_copy_res *res,
                break;
        }
        if (found_pending) {
-               spin_unlock(&server->nfs_client->cl_lock);
+               spin_unlock(&dst_server->nfs_client->cl_lock);
                kfree(copy);
                copy = tmp_copy;
                goto out;
@@ -165,19 +190,32 @@ static int handle_async_copy(struct nfs42_copy_res *res,
 
        memcpy(&copy->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
        init_completion(&copy->completion);
-       copy->parent_state = ctx->state;
+       copy->parent_dst_state = dst_ctx->state;
+       copy->parent_src_state = src_ctx->state;
 
-       list_add_tail(&copy->copies, &server->ss_copies);
-       spin_unlock(&server->nfs_client->cl_lock);
+       list_add_tail(&copy->copies, &dst_server->ss_copies);
+       spin_unlock(&dst_server->nfs_client->cl_lock);
+
+       if (dst_server != src_server) {
+               spin_lock(&src_server->nfs_client->cl_lock);
+               list_add_tail(&copy->src_copies, &src_server->ss_copies);
+               spin_unlock(&src_server->nfs_client->cl_lock);
+       }
 
        status = wait_for_completion_interruptible(&copy->completion);
-       spin_lock(&server->nfs_client->cl_lock);
+       spin_lock(&dst_server->nfs_client->cl_lock);
        list_del_init(&copy->copies);
-       spin_unlock(&server->nfs_client->cl_lock);
+       spin_unlock(&dst_server->nfs_client->cl_lock);
+       if (dst_server != src_server) {
+               spin_lock(&src_server->nfs_client->cl_lock);
+               list_del_init(&copy->src_copies);
+               spin_unlock(&src_server->nfs_client->cl_lock);
+       }
        if (status == -ERESTARTSYS) {
                goto out_cancel;
-       } else if (copy->flags) {
+       } else if (copy->flags || copy->error == NFS4ERR_PARTNER_NO_AUTH) {
                status = -EAGAIN;
+               *restart = true;
                goto out_cancel;
        }
 out:
@@ -185,12 +223,14 @@ out:
        memcpy(&res->write_res.verifier, &copy->verf, sizeof(copy->verf));
        status = -copy->error;
 
+out_free:
        kfree(copy);
        return status;
 out_cancel:
        nfs42_do_offload_cancel_async(dst, &copy->stateid);
-       kfree(copy);
-       return status;
+       if (!nfs42_files_from_same_server(src, dst))
+               nfs42_do_offload_cancel_async(src, src_stateid);
+       goto out_free;
 }
 
 static int process_copy_commit(struct file *dst, loff_t pos_dst,
@@ -222,7 +262,10 @@ static ssize_t _nfs42_proc_copy(struct file *src,
                                struct file *dst,
                                struct nfs_lock_context *dst_lock,
                                struct nfs42_copy_args *args,
-                               struct nfs42_copy_res *res)
+                               struct nfs42_copy_res *res,
+                               struct nl4_server *nss,
+                               nfs4_stateid *cnr_stateid,
+                               bool *restart)
 {
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
@@ -230,17 +273,23 @@ static ssize_t _nfs42_proc_copy(struct file *src,
                .rpc_resp = res,
        };
        struct inode *dst_inode = file_inode(dst);
-       struct nfs_server *server = NFS_SERVER(dst_inode);
+       struct inode *src_inode = file_inode(src);
+       struct nfs_server *dst_server = NFS_SERVER(dst_inode);
+       struct nfs_server *src_server = NFS_SERVER(src_inode);
        loff_t pos_src = args->src_pos;
        loff_t pos_dst = args->dst_pos;
        size_t count = args->count;
        ssize_t status;
 
-       status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
-                                    src_lock, FMODE_READ);
-       if (status)
-               return status;
-
+       if (nss) {
+               args->cp_src = nss;
+               nfs4_stateid_copy(&args->src_stateid, cnr_stateid);
+       } else {
+               status = nfs4_set_rw_stateid(&args->src_stateid,
+                               src_lock->open_context, src_lock, FMODE_READ);
+               if (status)
+                       return status;
+       }
        status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,
                        pos_src, pos_src + (loff_t)count - 1);
        if (status)
@@ -262,13 +311,15 @@ static ssize_t _nfs42_proc_copy(struct file *src,
                if (!res->commit_res.verf)
                        return -ENOMEM;
        }
+       set_bit(NFS_CLNT_SRC_SSC_COPY_STATE,
+               &src_lock->open_context->state->flags);
        set_bit(NFS_CLNT_DST_SSC_COPY_STATE,
                &dst_lock->open_context->state->flags);
 
-       status = nfs4_call_sync(server->client, server, &msg,
+       status = nfs4_call_sync(dst_server->client, dst_server, &msg,
                                &args->seq_args, &res->seq_res, 0);
        if (status == -ENOTSUPP)
-               server->caps &= ~NFS_CAP_COPY;
+               dst_server->caps &= ~NFS_CAP_COPY;
        if (status)
                goto out;
 
@@ -280,8 +331,8 @@ static ssize_t _nfs42_proc_copy(struct file *src,
        }
 
        if (!res->synchronous) {
-               status = handle_async_copy(res, server, src, dst,
-                               &args->src_stateid);
+               status = handle_async_copy(res, dst_server, src_server, src,
+                               dst, &args->src_stateid, restart);
                if (status)
                        return status;
        }
@@ -304,8 +355,9 @@ out:
 }
 
 ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
-                       struct file *dst, loff_t pos_dst,
-                       size_t count)
+                       struct file *dst, loff_t pos_dst, size_t count,
+                       struct nl4_server *nss,
+                       nfs4_stateid *cnr_stateid, bool sync)
 {
        struct nfs_server *server = NFS_SERVER(file_inode(dst));
        struct nfs_lock_context *src_lock;
@@ -316,7 +368,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
                .dst_fh         = NFS_FH(file_inode(dst)),
                .dst_pos        = pos_dst,
                .count          = count,
-               .sync           = false,
+               .sync           = sync,
        };
        struct nfs42_copy_res res;
        struct nfs4_exception src_exception = {
@@ -328,6 +380,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
                .stateid        = &args.dst_stateid,
        };
        ssize_t err, err2;
+       bool restart = false;
 
        src_lock = nfs_get_lock_context(nfs_file_open_context(src));
        if (IS_ERR(src_lock))
@@ -347,21 +400,33 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
                inode_lock(file_inode(dst));
                err = _nfs42_proc_copy(src, src_lock,
                                dst, dst_lock,
-                               &args, &res);
+                               &args, &res,
+                               nss, cnr_stateid, &restart);
                inode_unlock(file_inode(dst));
 
                if (err >= 0)
                        break;
-               if (err == -ENOTSUPP) {
+               if (err == -ENOTSUPP &&
+                               nfs42_files_from_same_server(src, dst)) {
                        err = -EOPNOTSUPP;
                        break;
                } else if (err == -EAGAIN) {
-                       dst_exception.retry = 1;
-                       continue;
+                       if (!restart) {
+                               dst_exception.retry = 1;
+                               continue;
+                       }
+                       break;
                } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {
                        args.sync = true;
                        dst_exception.retry = 1;
                        continue;
+               } else if ((err == -ESTALE ||
+                               err == -NFS4ERR_OFFLOAD_DENIED ||
+                               err == -ENOTSUPP) &&
+                               !nfs42_files_from_same_server(src, dst)) {
+                       nfs42_do_offload_cancel_async(src, &args.src_stateid);
+                       err = -EOPNOTSUPP;
+                       break;
                }
 
                err2 = nfs4_handle_exception(server, err, &src_exception);
@@ -459,6 +524,76 @@ static int nfs42_do_offload_cancel_async(struct file *dst,
        return status;
 }
 
+static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
+                                  struct nfs42_copy_notify_args *args,
+                                  struct nfs42_copy_notify_res *res)
+{
+       struct nfs_server *src_server = NFS_SERVER(file_inode(src));
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY_NOTIFY],
+               .rpc_argp = args,
+               .rpc_resp = res,
+       };
+       int status;
+       struct nfs_open_context *ctx;
+       struct nfs_lock_context *l_ctx;
+
+       ctx = get_nfs_open_context(nfs_file_open_context(src));
+       l_ctx = nfs_get_lock_context(ctx);
+       if (IS_ERR(l_ctx))
+               return PTR_ERR(l_ctx);
+
+       status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx,
+                                    FMODE_READ);
+       nfs_put_lock_context(l_ctx);
+       if (status)
+               return status;
+
+       status = nfs4_call_sync(src_server->client, src_server, &msg,
+                               &args->cna_seq_args, &res->cnr_seq_res, 0);
+       if (status == -ENOTSUPP)
+               src_server->caps &= ~NFS_CAP_COPY_NOTIFY;
+
+       put_nfs_open_context(nfs_file_open_context(src));
+       return status;
+}
+
+int nfs42_proc_copy_notify(struct file *src, struct file *dst,
+                               struct nfs42_copy_notify_res *res)
+{
+       struct nfs_server *src_server = NFS_SERVER(file_inode(src));
+       struct nfs42_copy_notify_args *args;
+       struct nfs4_exception exception = {
+               .inode = file_inode(src),
+       };
+       int status;
+
+       if (!(src_server->caps & NFS_CAP_COPY_NOTIFY))
+               return -EOPNOTSUPP;
+
+       args = kzalloc(sizeof(struct nfs42_copy_notify_args), GFP_NOFS);
+       if (args == NULL)
+               return -ENOMEM;
+
+       args->cna_src_fh  = NFS_FH(file_inode(src)),
+       args->cna_dst.nl4_type = NL4_NETADDR;
+       nfs42_set_netaddr(dst, &args->cna_dst.u.nl4_addr);
+       exception.stateid = &args->cna_src_stateid;
+
+       do {
+               status = _nfs42_proc_copy_notify(src, dst, args, res);
+               if (status == -ENOTSUPP) {
+                       status = -EOPNOTSUPP;
+                       goto out;
+               }
+               status = nfs4_handle_exception(src_server, status, &exception);
+       } while (exception.retry);
+
+out:
+       kfree(args);
+       return status;
+}
+
 static loff_t _nfs42_proc_llseek(struct file *filep,
                struct nfs_lock_context *lock, loff_t offset, int whence)
 {
index aed865a..c03f324 100644 (file)
 #define encode_copy_maxsz              (op_encode_hdr_maxsz +          \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE) + \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE) + \
-                                        2 + 2 + 2 + 1 + 1 + 1)
+                                        2 + 2 + 2 + 1 + 1 + 1 +\
+                                        1 + /* One cnr_source_server */\
+                                        1 + /* nl4_type */ \
+                                        1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
 #define decode_copy_maxsz              (op_decode_hdr_maxsz + \
                                         NFS42_WRITE_RES_SIZE + \
                                         1 /* cr_consecutive */ + \
 #define encode_offload_cancel_maxsz    (op_encode_hdr_maxsz + \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE))
 #define decode_offload_cancel_maxsz    (op_decode_hdr_maxsz)
+#define encode_copy_notify_maxsz       (op_encode_hdr_maxsz + \
+                                        XDR_QUADLEN(NFS4_STATEID_SIZE) + \
+                                        1 + /* nl4_type */ \
+                                        1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
+#define decode_copy_notify_maxsz       (op_decode_hdr_maxsz + \
+                                        3 + /* cnr_lease_time */\
+                                        XDR_QUADLEN(NFS4_STATEID_SIZE) + \
+                                        1 + /* Support 1 cnr_source_server */\
+                                        1 + /* nl4_type */ \
+                                        1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
 #define encode_deallocate_maxsz                (op_encode_hdr_maxsz + \
                                         encode_fallocate_maxsz)
 #define decode_deallocate_maxsz                (op_decode_hdr_maxsz)
                                         decode_sequence_maxsz + \
                                         decode_putfh_maxsz + \
                                         decode_offload_cancel_maxsz)
+#define NFS4_enc_copy_notify_sz                (compound_encode_hdr_maxsz + \
+                                        encode_putfh_maxsz + \
+                                        encode_copy_notify_maxsz)
+#define NFS4_dec_copy_notify_sz                (compound_decode_hdr_maxsz + \
+                                        decode_putfh_maxsz + \
+                                        decode_copy_notify_maxsz)
 #define NFS4_enc_deallocate_sz         (compound_encode_hdr_maxsz + \
                                         encode_sequence_maxsz + \
                                         encode_putfh_maxsz + \
@@ -166,6 +185,26 @@ static void encode_allocate(struct xdr_stream *xdr,
        encode_fallocate(xdr, args);
 }
 
+static void encode_nl4_server(struct xdr_stream *xdr,
+                             const struct nl4_server *ns)
+{
+       encode_uint32(xdr, ns->nl4_type);
+       switch (ns->nl4_type) {
+       case NL4_NAME:
+       case NL4_URL:
+               encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
+               break;
+       case NL4_NETADDR:
+               encode_string(xdr, ns->u.nl4_addr.netid_len,
+                             ns->u.nl4_addr.netid);
+               encode_string(xdr, ns->u.nl4_addr.addr_len,
+                             ns->u.nl4_addr.addr);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+       }
+}
+
 static void encode_copy(struct xdr_stream *xdr,
                        const struct nfs42_copy_args *args,
                        struct compound_hdr *hdr)
@@ -180,7 +219,12 @@ static void encode_copy(struct xdr_stream *xdr,
 
        encode_uint32(xdr, 1); /* consecutive = true */
        encode_uint32(xdr, args->sync);
-       encode_uint32(xdr, 0); /* src server list */
+       if (args->cp_src == NULL) { /* intra-ssc */
+               encode_uint32(xdr, 0); /* no src server list */
+               return;
+       }
+       encode_uint32(xdr, 1); /* supporting 1 server */
+       encode_nl4_server(xdr, args->cp_src);
 }
 
 static void encode_offload_cancel(struct xdr_stream *xdr,
@@ -191,6 +235,15 @@ static void encode_offload_cancel(struct xdr_stream *xdr,
        encode_nfs4_stateid(xdr, &args->osa_stateid);
 }
 
+static void encode_copy_notify(struct xdr_stream *xdr,
+                              const struct nfs42_copy_notify_args *args,
+                              struct compound_hdr *hdr)
+{
+       encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
+       encode_nfs4_stateid(xdr, &args->cna_src_stateid);
+       encode_nl4_server(xdr, &args->cna_dst);
+}
+
 static void encode_deallocate(struct xdr_stream *xdr,
                              const struct nfs42_falloc_args *args,
                              struct compound_hdr *hdr)
@@ -355,6 +408,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
 }
 
 /*
+ * Encode COPY_NOTIFY request
+ */
+static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
+                                    struct xdr_stream *xdr,
+                                    const void *data)
+{
+       const struct nfs42_copy_notify_args *args = data;
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
+       };
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->cna_seq_args, &hdr);
+       encode_putfh(xdr, args->cna_src_fh, &hdr);
+       encode_copy_notify(xdr, args, &hdr);
+       encode_nops(&hdr);
+}
+
+/*
  * Encode DEALLOCATE request
  */
 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
@@ -490,6 +562,58 @@ static int decode_write_response(struct xdr_stream *xdr,
        return decode_verifier(xdr, &res->verifier.verifier);
 }
 
+static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
+{
+       struct nfs42_netaddr *naddr;
+       uint32_t dummy;
+       char *dummy_str;
+       __be32 *p;
+       int status;
+
+       /* nl_type */
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               return -EIO;
+       ns->nl4_type = be32_to_cpup(p);
+       switch (ns->nl4_type) {
+       case NL4_NAME:
+       case NL4_URL:
+               status = decode_opaque_inline(xdr, &dummy, &dummy_str);
+               if (unlikely(status))
+                       return status;
+               if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
+                       return -EIO;
+               memcpy(&ns->u.nl4_str, dummy_str, dummy);
+               ns->u.nl4_str_sz = dummy;
+               break;
+       case NL4_NETADDR:
+               naddr = &ns->u.nl4_addr;
+
+               /* netid string */
+               status = decode_opaque_inline(xdr, &dummy, &dummy_str);
+               if (unlikely(status))
+                       return status;
+               if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
+                       return -EIO;
+               naddr->netid_len = dummy;
+               memcpy(naddr->netid, dummy_str, naddr->netid_len);
+
+               /* uaddr string */
+               status = decode_opaque_inline(xdr, &dummy, &dummy_str);
+               if (unlikely(status))
+                       return status;
+               if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
+                       return -EIO;
+               naddr->addr_len = dummy;
+               memcpy(naddr->addr, dummy_str, naddr->addr_len);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               return -EIO;
+       }
+       return 0;
+}
+
 static int decode_copy_requirements(struct xdr_stream *xdr,
                                    struct nfs42_copy_res *res) {
        __be32 *p;
@@ -529,6 +653,42 @@ static int decode_offload_cancel(struct xdr_stream *xdr,
        return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
 }
 
+static int decode_copy_notify(struct xdr_stream *xdr,
+                             struct nfs42_copy_notify_res *res)
+{
+       __be32 *p;
+       int status, count;
+
+       status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
+       if (status)
+               return status;
+       /* cnr_lease_time */
+       p = xdr_inline_decode(xdr, 12);
+       if (unlikely(!p))
+               return -EIO;
+       p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
+       res->cnr_lease_time.nseconds = be32_to_cpup(p);
+
+       status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
+       if (unlikely(status))
+               return -EIO;
+
+       /* number of source addresses */
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               return -EIO;
+
+       count = be32_to_cpup(p);
+       if (count > 1)
+               pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
+                        __func__, count);
+
+       status = decode_nl4_server(xdr, &res->cnr_src);
+       if (unlikely(status))
+               return -EIO;
+       return 0;
+}
+
 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
 {
        return decode_op_hdr(xdr, OP_DEALLOCATE);
@@ -657,6 +817,32 @@ out:
 }
 
 /*
+ * Decode COPY_NOTIFY response
+ */
+static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
+                                   struct xdr_stream *xdr,
+                                   void *data)
+{
+       struct nfs42_copy_notify_res *res = data;
+       struct compound_hdr hdr;
+       int status;
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+       status = decode_copy_notify(xdr, res);
+
+out:
+       return status;
+}
+
+/*
  * Decode DEALLOCATE request
  */
 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
index 16b2e5c..a7a73b1 100644 (file)
@@ -166,9 +166,9 @@ enum {
        NFS_STATE_RECOVERY_FAILED,      /* OPEN stateid state recovery failed */
        NFS_STATE_MAY_NOTIFY_LOCK,      /* server may CB_NOTIFY_LOCK */
        NFS_STATE_CHANGE_WAIT,          /* A state changing operation is outstanding */
-#ifdef CONFIG_NFS_V4_2
        NFS_CLNT_DST_SSC_COPY_STATE,    /* dst server open state on client*/
-#endif /* CONFIG_NFS_V4_2 */
+       NFS_CLNT_SRC_SSC_COPY_STATE,    /* src server open state on client*/
+       NFS_SRV_SSC_COPY_STATE,         /* ssc state on the dst server */
 };
 
 struct nfs4_state {
@@ -311,6 +311,13 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
                const struct nfs_open_context *ctx,
                const struct nfs_lock_context *l_ctx,
                fmode_t fmode);
+extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+                            struct nfs_fattr *fattr, struct nfs4_label *label,
+                            struct inode *inode);
+extern int update_open_stateid(struct nfs4_state *state,
+                               const nfs4_stateid *open_stateid,
+                               const nfs4_stateid *deleg_stateid,
+                               fmode_t fmode);
 
 extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
                struct nfs_fsinfo *fsinfo);
@@ -445,6 +452,8 @@ extern void nfs4_set_lease_period(struct nfs_client *clp,
 
 
 /* nfs4state.c */
+extern const nfs4_stateid current_stateid;
+
 const struct cred *nfs4_get_clid_cred(struct nfs_client *clp);
 const struct cred *nfs4_get_machine_cred(struct nfs_client *clp);
 const struct cred *nfs4_get_renew_cred(struct nfs_client *clp);
@@ -457,6 +466,8 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
                        struct nfs_client **, const struct cred *);
 extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
 extern void nfs41_notify_server(struct nfs_client *);
+bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1,
+                       struct nfs41_server_owner *o2);
 #else
 static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
 {
@@ -572,6 +583,12 @@ static inline bool nfs4_stateid_is_newer(const nfs4_stateid *s1, const nfs4_stat
        return (s32)(be32_to_cpu(s1->seqid) - be32_to_cpu(s2->seqid)) > 0;
 }
 
+static inline bool nfs4_stateid_match_or_older(const nfs4_stateid *dst, const nfs4_stateid *src)
+{
+       return nfs4_stateid_match_other(dst, src) &&
+               !(src->seqid && nfs4_stateid_is_newer(dst, src));
+}
+
 static inline void nfs4_stateid_seqid_inc(nfs4_stateid *s1)
 {
        u32 seqid = be32_to_cpu(s1->seqid);
index da62040..460d625 100644 (file)
@@ -629,7 +629,7 @@ out:
 /*
  * Returns true if the server major ids match
  */
-static bool
+bool
 nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1,
                                struct nfs41_server_owner *o2)
 {
@@ -879,14 +879,17 @@ static int nfs4_set_client(struct nfs_server *server,
        };
        struct nfs_client *clp;
 
-       if (minorversion > 0 && proto == XPRT_TRANSPORT_TCP)
+       if (minorversion == 0)
+               __set_bit(NFS_CS_REUSEPORT, &cl_init.init_flags);
+       else if (proto == XPRT_TRANSPORT_TCP)
                cl_init.nconnect = nconnect;
+
        if (server->flags & NFS_MOUNT_NORESVPORT)
-               set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
+               __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
        if (server->options & NFS_OPTION_MIGRATION)
-               set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
+               __set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
        if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status))
-               set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);
+               __set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);
        server->port = rpc_get_port(addr);
 
        /* Allocate or find a client reference we can use */
index 339663d..620de90 100644 (file)
@@ -133,14 +133,55 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
                                      struct file *file_out, loff_t pos_out,
                                      size_t count, unsigned int flags)
 {
+       struct nfs42_copy_notify_res *cn_resp = NULL;
+       struct nl4_server *nss = NULL;
+       nfs4_stateid *cnrs = NULL;
+       ssize_t ret;
+       bool sync = false;
+
        /* Only offload copy if superblock is the same */
-       if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
+       if (file_in->f_op != &nfs4_file_operations)
                return -EXDEV;
        if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY))
                return -EOPNOTSUPP;
        if (file_inode(file_in) == file_inode(file_out))
                return -EOPNOTSUPP;
-       return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
+       /* if the copy size if smaller than 2 RPC payloads, make it
+        * synchronous
+        */
+       if (count <= 2 * NFS_SERVER(file_inode(file_in))->rsize)
+               sync = true;
+retry:
+       if (!nfs42_files_from_same_server(file_in, file_out)) {
+               /* for inter copy, if copy size if smaller than 12 RPC
+                * payloads, fallback to traditional copy. There are
+                * 14 RPCs during an NFSv4.x mount between source/dest
+                * servers.
+                */
+               if (sync ||
+                       count <= 14 * NFS_SERVER(file_inode(file_in))->rsize)
+                       return -EOPNOTSUPP;
+               cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res),
+                               GFP_NOFS);
+               if (unlikely(cn_resp == NULL))
+                       return -ENOMEM;
+
+               ret = nfs42_proc_copy_notify(file_in, file_out, cn_resp);
+               if (ret) {
+                       ret = -EOPNOTSUPP;
+                       goto out;
+               }
+               nss = &cn_resp->cnr_src;
+               cnrs = &cn_resp->cnr_stateid;
+       }
+       ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count,
+                               nss, cnrs, sync);
+out:
+       if (!nfs42_files_from_same_server(file_in, file_out))
+               kfree(cn_resp);
+       if (ret == -EAGAIN)
+               goto retry;
+       return ret;
 }
 
 static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
@@ -263,6 +304,102 @@ out_unlock:
 out:
        return ret < 0 ? ret : count;
 }
+
+static int read_name_gen = 1;
+#define SSC_READ_NAME_BODY "ssc_read_%d"
+
+struct file *
+nfs42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh,
+               nfs4_stateid *stateid)
+{
+       struct nfs_fattr fattr;
+       struct file *filep, *res;
+       struct nfs_server *server;
+       struct inode *r_ino = NULL;
+       struct nfs_open_context *ctx;
+       struct nfs4_state_owner *sp;
+       char *read_name = NULL;
+       int len, status = 0;
+
+       server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
+
+       nfs_fattr_init(&fattr);
+
+       status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL);
+       if (status < 0) {
+               res = ERR_PTR(status);
+               goto out;
+       }
+
+       res = ERR_PTR(-ENOMEM);
+       len = strlen(SSC_READ_NAME_BODY) + 16;
+       read_name = kzalloc(len, GFP_NOFS);
+       if (read_name == NULL)
+               goto out;
+       snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
+
+       r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr,
+                       NULL);
+       if (IS_ERR(r_ino)) {
+               res = ERR_CAST(r_ino);
+               goto out_free_name;
+       }
+
+       filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, FMODE_READ,
+                                    r_ino->i_fop);
+       if (IS_ERR(filep)) {
+               res = ERR_CAST(filep);
+               goto out_free_name;
+       }
+       filep->f_mode |= FMODE_READ;
+
+       ctx = alloc_nfs_open_context(filep->f_path.dentry, filep->f_mode,
+                                       filep);
+       if (IS_ERR(ctx)) {
+               res = ERR_CAST(ctx);
+               goto out_filep;
+       }
+
+       res = ERR_PTR(-EINVAL);
+       sp = nfs4_get_state_owner(server, ctx->cred, GFP_KERNEL);
+       if (sp == NULL)
+               goto out_ctx;
+
+       ctx->state = nfs4_get_open_state(r_ino, sp);
+       if (ctx->state == NULL)
+               goto out_stateowner;
+
+       set_bit(NFS_SRV_SSC_COPY_STATE, &ctx->state->flags);
+       set_bit(NFS_OPEN_STATE, &ctx->state->flags);
+       memcpy(&ctx->state->open_stateid.other, &stateid->other,
+              NFS4_STATEID_OTHER_SIZE);
+       update_open_stateid(ctx->state, stateid, NULL, filep->f_mode);
+
+       nfs_file_set_open_context(filep, ctx);
+       put_nfs_open_context(ctx);
+
+       file_ra_state_init(&filep->f_ra, filep->f_mapping->host->i_mapping);
+       res = filep;
+out_free_name:
+       kfree(read_name);
+out:
+       return res;
+out_stateowner:
+       nfs4_put_state_owner(sp);
+out_ctx:
+       put_nfs_open_context(ctx);
+out_filep:
+       fput(filep);
+       goto out_free_name;
+}
+EXPORT_SYMBOL_GPL(nfs42_ssc_open);
+void nfs42_ssc_close(struct file *filep)
+{
+       struct nfs_open_context *ctx = nfs_file_open_context(filep);
+
+       ctx->state->flags = 0;
+}
+EXPORT_SYMBOL_GPL(nfs42_ssc_close);
 #endif /* CONFIG_NFS_V4_2 */
 
 const struct file_operations nfs4_file_operations = {
index caacf5e..76d3716 100644 (file)
@@ -91,7 +91,6 @@ struct nfs4_opendata;
 static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
 static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
 static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
-static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label, struct inode *inode);
 static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);
 static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
                            struct nfs_fattr *fattr, struct iattr *sattr,
@@ -476,6 +475,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_EXPIRED:
                case -NFS4ERR_BAD_STATEID:
+               case -NFS4ERR_PARTNER_NO_AUTH:
                        if (inode != NULL && stateid != NULL) {
                                nfs_inode_find_state_and_recover(inode,
                                                stateid);
@@ -521,9 +521,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                case -NFS4ERR_DEADSESSION:
                case -NFS4ERR_SEQ_FALSE_RETRY:
                case -NFS4ERR_SEQ_MISORDERED:
-                       dprintk("%s ERROR: %d Reset session\n", __func__,
-                               errorcode);
-                       nfs4_schedule_session_recovery(clp->cl_session, errorcode);
+                       /* Handled in nfs41_sequence_process() */
                        goto wait_on_recovery;
 #endif /* defined(CONFIG_NFS_V4_1) */
                case -NFS4ERR_FILE_OPEN:
@@ -782,6 +780,7 @@ static int nfs41_sequence_process(struct rpc_task *task,
        struct nfs4_session *session;
        struct nfs4_slot *slot = res->sr_slot;
        struct nfs_client *clp;
+       int status;
        int ret = 1;
 
        if (slot == NULL)
@@ -793,8 +792,13 @@ static int nfs41_sequence_process(struct rpc_task *task,
        session = slot->table->session;
 
        trace_nfs4_sequence_done(session, res);
+
+       status = res->sr_status;
+       if (task->tk_status == -NFS4ERR_DEADSESSION)
+               status = -NFS4ERR_DEADSESSION;
+
        /* Check the SEQUENCE operation status */
-       switch (res->sr_status) {
+       switch (status) {
        case 0:
                /* Mark this sequence number as having been acked */
                nfs4_slot_sequence_acked(slot, slot->seq_nr);
@@ -866,6 +870,10 @@ static int nfs41_sequence_process(struct rpc_task *task,
                 */
                slot->seq_nr = slot->seq_nr_highest_sent;
                goto out_retry;
+       case -NFS4ERR_BADSESSION:
+       case -NFS4ERR_DEADSESSION:
+       case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+               goto session_recover;
        default:
                /* Just update the slot sequence no. */
                slot->seq_done = 1;
@@ -876,8 +884,10 @@ out:
 out_noaction:
        return ret;
 session_recover:
-       nfs4_schedule_session_recovery(session, res->sr_status);
-       goto retry_nowait;
+       nfs4_schedule_session_recovery(session, status);
+       dprintk("%s ERROR: %d Reset session\n", __func__, status);
+       nfs41_sequence_free_slot(res);
+       goto out;
 retry_new_seq:
        ++slot->seq_nr;
 retry_nowait:
@@ -1716,7 +1726,7 @@ static void nfs_state_clear_delegation(struct nfs4_state *state)
        write_sequnlock(&state->seqlock);
 }
 
-static int update_open_stateid(struct nfs4_state *state,
+int update_open_stateid(struct nfs4_state *state,
                const nfs4_stateid *open_stateid,
                const nfs4_stateid *delegation,
                fmode_t fmode)
@@ -1737,7 +1747,7 @@ static int update_open_stateid(struct nfs4_state *state,
                ret = 1;
        }
 
-       deleg_cur = rcu_dereference(nfsi->delegation);
+       deleg_cur = nfs4_get_valid_delegation(state->inode);
        if (deleg_cur == NULL)
                goto no_delegation;
 
@@ -1749,7 +1759,7 @@ static int update_open_stateid(struct nfs4_state *state,
 
        if (delegation == NULL)
                delegation = &deleg_cur->stateid;
-       else if (!nfs4_stateid_match(&deleg_cur->stateid, delegation))
+       else if (!nfs4_stateid_match_other(&deleg_cur->stateid, delegation))
                goto no_delegation_unlock;
 
        nfs_mark_delegation_referenced(deleg_cur);
@@ -1796,7 +1806,7 @@ static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmo
 
        fmode &= FMODE_READ|FMODE_WRITE;
        rcu_read_lock();
-       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       delegation = nfs4_get_valid_delegation(inode);
        if (delegation == NULL || (delegation->type & fmode) == fmode) {
                rcu_read_unlock();
                return;
@@ -2188,7 +2198,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
                case -NFS4ERR_BAD_HIGH_SLOT:
                case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
                case -NFS4ERR_DEADSESSION:
-                       nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
                        return -EAGAIN;
                case -NFS4ERR_STALE_CLIENTID:
                case -NFS4ERR_STALE_STATEID:
@@ -4062,7 +4071,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
        return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
 }
 
-static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
                                struct nfs_fattr *fattr, struct nfs4_label *label,
                                struct inode *inode)
 {
@@ -5098,12 +5107,12 @@ static bool nfs4_stateid_is_current(nfs4_stateid *stateid,
                const struct nfs_lock_context *l_ctx,
                fmode_t fmode)
 {
-       nfs4_stateid current_stateid;
+       nfs4_stateid _current_stateid;
 
        /* If the current stateid represents a lost lock, then exit */
-       if (nfs4_set_rw_stateid(&current_stateid, ctx, l_ctx, fmode) == -EIO)
+       if (nfs4_set_rw_stateid(&_current_stateid, ctx, l_ctx, fmode) == -EIO)
                return true;
-       return nfs4_stateid_match(stateid, &current_stateid);
+       return nfs4_stateid_match(stateid, &_current_stateid);
 }
 
 static bool nfs4_error_stateid_expired(int err)
@@ -6196,10 +6205,13 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
                task->tk_status = 0;
                break;
        case -NFS4ERR_OLD_STATEID:
-               if (nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
-                       goto out_restart;
-               task->tk_status = 0;
-               break;
+               if (!nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
+                       nfs4_stateid_seqid_inc(&data->stateid);
+               if (data->args.bitmask) {
+                       data->args.bitmask = NULL;
+                       data->res.fattr = NULL;
+               }
+               goto out_restart;
        case -NFS4ERR_ACCESS:
                if (data->args.bitmask) {
                        data->args.bitmask = NULL;
@@ -6214,6 +6226,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
                if (exception.retry)
                        goto out_restart;
        }
+       nfs_delegation_mark_returned(data->inode, data->args.stateid);
        data->rpc_status = task->tk_status;
        return;
 out_restart:
@@ -6243,8 +6256,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
 
        d_data = (struct nfs4_delegreturndata *)data;
 
-       if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task))
+       if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task)) {
+               nfs4_sequence_done(task, &d_data->res.seq_res);
                return;
+       }
 
        lo = d_data->args.lr_args ? d_data->args.lr_args->layout : NULL;
        if (lo && !pnfs_layout_is_valid(lo)) {
@@ -7820,6 +7835,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a,
 static void
 nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
 {
+       struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp;
+       struct nfs_client *clp = args->client;
+
+       switch (task->tk_status) {
+       case -NFS4ERR_BADSESSION:
+       case -NFS4ERR_DEADSESSION:
+               nfs4_schedule_session_recovery(clp->cl_session,
+                               task->tk_status);
+       }
 }
 
 static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
@@ -8867,8 +8891,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
        case -NFS4ERR_BADSESSION:
        case -NFS4ERR_DEADSESSION:
        case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
-               nfs4_schedule_session_recovery(clp->cl_session,
-                               task->tk_status);
                break;
        default:
                nfs4_schedule_lease_recovery(clp);
@@ -9897,6 +9919,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
                | NFS_CAP_ALLOCATE
                | NFS_CAP_COPY
                | NFS_CAP_OFFLOAD_CANCEL
+               | NFS_CAP_COPY_NOTIFY
                | NFS_CAP_DEALLOCATE
                | NFS_CAP_SEEK
                | NFS_CAP_LAYOUTSTATS
index 0c6d53d..3455232 100644 (file)
@@ -60,6 +60,7 @@
 #include "nfs4session.h"
 #include "pnfs.h"
 #include "netns.h"
+#include "nfs4trace.h"
 
 #define NFSDBG_FACILITY                NFSDBG_STATE
 
@@ -1407,7 +1408,7 @@ nfs_state_find_lock_state_by_stateid(struct nfs4_state *state,
        list_for_each_entry(pos, &state->lock_states, ls_locks) {
                if (!test_bit(NFS_LOCK_INITIALIZED, &pos->ls_flags))
                        continue;
-               if (nfs4_stateid_match_other(&pos->ls_stateid, stateid))
+               if (nfs4_stateid_match_or_older(&pos->ls_stateid, stateid))
                        return pos;
        }
        return NULL;
@@ -1441,12 +1442,13 @@ void nfs_inode_find_state_and_recover(struct inode *inode,
                state = ctx->state;
                if (state == NULL)
                        continue;
-               if (nfs4_stateid_match_other(&state->stateid, stateid) &&
+               if (nfs4_stateid_match_or_older(&state->stateid, stateid) &&
                    nfs4_state_mark_reclaim_nograce(clp, state)) {
                        found = true;
                        continue;
                }
-               if (nfs4_stateid_match_other(&state->open_stateid, stateid) &&
+               if (test_bit(NFS_OPEN_STATE, &state->flags) &&
+                   nfs4_stateid_match_or_older(&state->open_stateid, stateid) &&
                    nfs4_state_mark_reclaim_nograce(clp, state)) {
                        found = true;
                        continue;
@@ -1556,16 +1558,32 @@ static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state
 {
        struct nfs4_copy_state *copy;
 
-       if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags))
+       if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
+               !test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags))
                return;
 
        spin_lock(&sp->so_server->nfs_client->cl_lock);
        list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {
-               if (!nfs4_stateid_match_other(&state->stateid, &copy->parent_state->stateid))
-                       continue;
+               if ((test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
+                               !nfs4_stateid_match_other(&state->stateid,
+                               &copy->parent_dst_state->stateid)))
+                               continue;
                copy->flags = 1;
-               complete(&copy->completion);
-               break;
+               if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
+                               &state->flags)) {
+                       clear_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags);
+                       complete(&copy->completion);
+               }
+       }
+       list_for_each_entry(copy, &sp->so_server->ss_copies, src_copies) {
+               if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) &&
+                               !nfs4_stateid_match_other(&state->stateid,
+                               &copy->parent_src_state->stateid)))
+                               continue;
+               copy->flags = 1;
+               if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
+                               &state->flags))
+                       complete(&copy->completion);
        }
        spin_unlock(&sp->so_server->nfs_client->cl_lock);
 }
@@ -1593,6 +1611,7 @@ static int __nfs4_reclaim_open_state(struct nfs4_state_owner *sp, struct nfs4_st
        if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) {
                spin_lock(&state->state_lock);
                list_for_each_entry(lock, &state->lock_states, ls_locks) {
+                       trace_nfs4_state_lock_reclaim(state, lock);
                        if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
                                pr_warn_ratelimited("NFS: %s: Lock reclaim failed!\n", __func__);
                }
@@ -1609,6 +1628,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
        struct nfs4_state *state;
        unsigned int loop = 0;
        int status = 0;
+#ifdef CONFIG_NFS_V4_2
+       bool found_ssc_copy_state = false;
+#endif /* CONFIG_NFS_V4_2 */
 
        /* Note: we rely on the sp->so_states list being ordered 
         * so that we always reclaim open(O_RDWR) and/or open(O_WRITE)
@@ -1628,6 +1650,13 @@ restart:
                        continue;
                if (state->state == 0)
                        continue;
+#ifdef CONFIG_NFS_V4_2
+               if (test_bit(NFS_SRV_SSC_COPY_STATE, &state->flags)) {
+                       nfs4_state_mark_recovery_failed(state, -EIO);
+                       found_ssc_copy_state = true;
+                       continue;
+               }
+#endif /* CONFIG_NFS_V4_2 */
                refcount_inc(&state->count);
                spin_unlock(&sp->so_lock);
                status = __nfs4_reclaim_open_state(sp, state, ops);
@@ -1682,6 +1711,10 @@ restart:
        }
        raw_write_seqcount_end(&sp->so_reclaim_seqcount);
        spin_unlock(&sp->so_lock);
+#ifdef CONFIG_NFS_V4_2
+       if (found_ssc_copy_state)
+               return -EIO;
+#endif /* CONFIG_NFS_V4_2 */
        return 0;
 out_err:
        nfs4_put_open_state(state);
@@ -2508,6 +2541,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
 
        /* Ensure exclusive access to NFSv4 state */
        do {
+               trace_nfs4_state_mgr(clp);
                clear_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
                if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
                        section = "purge state";
@@ -2621,6 +2655,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
 out_error:
        if (strlen(section))
                section_sep = ": ";
+       trace_nfs4_state_mgr_failed(clp, section, status);
        pr_warn_ratelimited("NFS: state manager%s%s failed on NFSv4 server %s"
                        " with error %d\n", section_sep, section,
                        clp->cl_hostname, -status);
index 04c5706..2c9cbad 100644 (file)
@@ -92,8 +92,8 @@ static void nfs4_evict_inode(struct inode *inode)
 {
        truncate_inode_pages_final(&inode->i_data);
        clear_inode(inode);
-       /* If we are holding a delegation, return it! */
-       nfs_inode_return_delegation_noreclaim(inode);
+       /* If we are holding a delegation, return and free it */
+       nfs_inode_evict_delegation(inode);
        /* Note that above delegreturn would trigger pnfs return-on-close */
        pnfs_return_layout(inode);
        pnfs_destroy_layout(NFS_I(inode));
index b2f395f..e60b6fb 100644 (file)
@@ -562,6 +562,99 @@ TRACE_EVENT(nfs4_setup_sequence,
                )
 );
 
+TRACE_DEFINE_ENUM(NFS4CLNT_MANAGER_RUNNING);
+TRACE_DEFINE_ENUM(NFS4CLNT_CHECK_LEASE);
+TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_EXPIRED);
+TRACE_DEFINE_ENUM(NFS4CLNT_RECLAIM_REBOOT);
+TRACE_DEFINE_ENUM(NFS4CLNT_RECLAIM_NOGRACE);
+TRACE_DEFINE_ENUM(NFS4CLNT_DELEGRETURN);
+TRACE_DEFINE_ENUM(NFS4CLNT_SESSION_RESET);
+TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_CONFIRM);
+TRACE_DEFINE_ENUM(NFS4CLNT_SERVER_SCOPE_MISMATCH);
+TRACE_DEFINE_ENUM(NFS4CLNT_PURGE_STATE);
+TRACE_DEFINE_ENUM(NFS4CLNT_BIND_CONN_TO_SESSION);
+TRACE_DEFINE_ENUM(NFS4CLNT_MOVED);
+TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_MOVED);
+TRACE_DEFINE_ENUM(NFS4CLNT_DELEGATION_EXPIRED);
+TRACE_DEFINE_ENUM(NFS4CLNT_RUN_MANAGER);
+TRACE_DEFINE_ENUM(NFS4CLNT_DELEGRETURN_RUNNING);
+
+#define show_nfs4_clp_state(state) \
+       __print_flags(state, "|", \
+               { NFS4CLNT_MANAGER_RUNNING,     "MANAGER_RUNNING" }, \
+               { NFS4CLNT_CHECK_LEASE,         "CHECK_LEASE" }, \
+               { NFS4CLNT_LEASE_EXPIRED,       "LEASE_EXPIRED" }, \
+               { NFS4CLNT_RECLAIM_REBOOT,      "RECLAIM_REBOOT" }, \
+               { NFS4CLNT_RECLAIM_NOGRACE,     "RECLAIM_NOGRACE" }, \
+               { NFS4CLNT_DELEGRETURN,         "DELEGRETURN" }, \
+               { NFS4CLNT_SESSION_RESET,       "SESSION_RESET" }, \
+               { NFS4CLNT_LEASE_CONFIRM,       "LEASE_CONFIRM" }, \
+               { NFS4CLNT_SERVER_SCOPE_MISMATCH, \
+                                               "SERVER_SCOPE_MISMATCH" }, \
+               { NFS4CLNT_PURGE_STATE,         "PURGE_STATE" }, \
+               { NFS4CLNT_BIND_CONN_TO_SESSION, \
+                                               "BIND_CONN_TO_SESSION" }, \
+               { NFS4CLNT_MOVED,               "MOVED" }, \
+               { NFS4CLNT_LEASE_MOVED,         "LEASE_MOVED" }, \
+               { NFS4CLNT_DELEGATION_EXPIRED,  "DELEGATION_EXPIRED" }, \
+               { NFS4CLNT_RUN_MANAGER,         "RUN_MANAGER" }, \
+               { NFS4CLNT_DELEGRETURN_RUNNING, "DELEGRETURN_RUNNING" })
+
+TRACE_EVENT(nfs4_state_mgr,
+               TP_PROTO(
+                       const struct nfs_client *clp
+               ),
+
+               TP_ARGS(clp),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, state)
+                       __string(hostname, clp->cl_hostname)
+               ),
+
+               TP_fast_assign(
+                       __entry->state = clp->cl_state;
+                       __assign_str(hostname, clp->cl_hostname)
+               ),
+
+               TP_printk(
+                       "hostname=%s clp state=%s", __get_str(hostname),
+                       show_nfs4_clp_state(__entry->state)
+               )
+)
+
+TRACE_EVENT(nfs4_state_mgr_failed,
+               TP_PROTO(
+                       const struct nfs_client *clp,
+                       const char *section,
+                       int status
+               ),
+
+               TP_ARGS(clp, section, status),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(unsigned long, state)
+                       __string(hostname, clp->cl_hostname)
+                       __string(section, section)
+               ),
+
+               TP_fast_assign(
+                       __entry->error = status;
+                       __entry->state = clp->cl_state;
+                       __assign_str(hostname, clp->cl_hostname);
+                       __assign_str(section, section);
+               ),
+
+               TP_printk(
+                       "hostname=%s clp state=%s error=%ld (%s) section=%s",
+                       __get_str(hostname),
+                       show_nfs4_clp_state(__entry->state), -__entry->error,
+                       show_nfsv4_errors(__entry->error), __get_str(section)
+
+               )
+)
+
 TRACE_EVENT(nfs4_xdr_status,
                TP_PROTO(
                        const struct xdr_stream *xdr,
@@ -929,6 +1022,88 @@ TRACE_EVENT(nfs4_set_lock,
                )
 );
 
+TRACE_DEFINE_ENUM(LK_STATE_IN_USE);
+TRACE_DEFINE_ENUM(NFS_DELEGATED_STATE);
+TRACE_DEFINE_ENUM(NFS_OPEN_STATE);
+TRACE_DEFINE_ENUM(NFS_O_RDONLY_STATE);
+TRACE_DEFINE_ENUM(NFS_O_WRONLY_STATE);
+TRACE_DEFINE_ENUM(NFS_O_RDWR_STATE);
+TRACE_DEFINE_ENUM(NFS_STATE_RECLAIM_REBOOT);
+TRACE_DEFINE_ENUM(NFS_STATE_RECLAIM_NOGRACE);
+TRACE_DEFINE_ENUM(NFS_STATE_POSIX_LOCKS);
+TRACE_DEFINE_ENUM(NFS_STATE_RECOVERY_FAILED);
+TRACE_DEFINE_ENUM(NFS_STATE_MAY_NOTIFY_LOCK);
+TRACE_DEFINE_ENUM(NFS_STATE_CHANGE_WAIT);
+TRACE_DEFINE_ENUM(NFS_CLNT_DST_SSC_COPY_STATE);
+TRACE_DEFINE_ENUM(NFS_CLNT_SRC_SSC_COPY_STATE);
+TRACE_DEFINE_ENUM(NFS_SRV_SSC_COPY_STATE);
+
+#define show_nfs4_state_flags(flags) \
+       __print_flags(flags, "|", \
+               { LK_STATE_IN_USE,              "IN_USE" }, \
+               { NFS_DELEGATED_STATE,          "DELEGATED" }, \
+               { NFS_OPEN_STATE,               "OPEN" }, \
+               { NFS_O_RDONLY_STATE,           "O_RDONLY" }, \
+               { NFS_O_WRONLY_STATE,           "O_WRONLY" }, \
+               { NFS_O_RDWR_STATE,             "O_RDWR" }, \
+               { NFS_STATE_RECLAIM_REBOOT,     "RECLAIM_REBOOT" }, \
+               { NFS_STATE_RECLAIM_NOGRACE,    "RECLAIM_NOGRACE" }, \
+               { NFS_STATE_POSIX_LOCKS,        "POSIX_LOCKS" }, \
+               { NFS_STATE_RECOVERY_FAILED,    "RECOVERY_FAILED" }, \
+               { NFS_STATE_MAY_NOTIFY_LOCK,    "MAY_NOTIFY_LOCK" }, \
+               { NFS_STATE_CHANGE_WAIT,        "CHANGE_WAIT" }, \
+               { NFS_CLNT_DST_SSC_COPY_STATE,  "CLNT_DST_SSC_COPY" }, \
+               { NFS_CLNT_SRC_SSC_COPY_STATE,  "CLNT_SRC_SSC_COPY" }, \
+               { NFS_SRV_SSC_COPY_STATE,       "SRV_SSC_COPY" })
+
+#define show_nfs4_lock_flags(flags) \
+       __print_flags(flags, "|", \
+               { BIT(NFS_LOCK_INITIALIZED),    "INITIALIZED" }, \
+               { BIT(NFS_LOCK_LOST),           "LOST" })
+
+TRACE_EVENT(nfs4_state_lock_reclaim,
+               TP_PROTO(
+                       const struct nfs4_state *state,
+                       const struct nfs4_lock_state *lock
+               ),
+
+               TP_ARGS(state, lock),
+
+               TP_STRUCT__entry(
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(unsigned long, state_flags)
+                       __field(unsigned long, lock_flags)
+                       __field(int, stateid_seq)
+                       __field(u32, stateid_hash)
+               ),
+
+               TP_fast_assign(
+                       const struct inode *inode = state->inode;
+
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = NFS_FILEID(inode);
+                       __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
+                       __entry->state_flags = state->flags;
+                       __entry->lock_flags = lock->ls_flags;
+                       __entry->stateid_seq =
+                               be32_to_cpu(state->stateid.seqid);
+                       __entry->stateid_hash =
+                               nfs_stateid_hash(&state->stateid);
+               ),
+
+               TP_printk(
+                       "fileid=%02x:%02x:%llu fhandle=0x%08x "
+                       "stateid=%d:0x%08x state_flags=%s lock_flags=%s",
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid, __entry->fhandle,
+                       __entry->stateid_seq, __entry->stateid_hash,
+                       show_nfs4_state_flags(__entry->state_flags),
+                       show_nfs4_lock_flags(__entry->lock_flags)
+               )
+)
+
 DECLARE_EVENT_CLASS(nfs4_set_delegation_event,
                TP_PROTO(
                        const struct inode *inode,
index ab07db0..936c577 100644 (file)
@@ -1059,7 +1059,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
 }
 
 static __be32 *
-xdr_encode_nfstime4(__be32 *p, const struct timespec *t)
+xdr_encode_nfstime4(__be32 *p, const struct timespec64 *t)
 {
        p = xdr_encode_hyper(p, (__s64)t->tv_sec);
        *p++ = cpu_to_be32(t->tv_nsec);
@@ -1072,7 +1072,6 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
                                const struct nfs_server *server,
                                const uint32_t attrmask[])
 {
-       struct timespec ts;
        char owner_name[IDMAP_NAMESZ];
        char owner_group[IDMAP_NAMESZ];
        int owner_namelen = 0;
@@ -1161,16 +1160,14 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
        if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
                if (iap->ia_valid & ATTR_ATIME_SET) {
                        *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
-                       ts = timespec64_to_timespec(iap->ia_atime);
-                       p = xdr_encode_nfstime4(p, &ts);
+                       p = xdr_encode_nfstime4(p, &iap->ia_atime);
                } else
                        *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
        }
        if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
                if (iap->ia_valid & ATTR_MTIME_SET) {
                        *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
-                       ts = timespec64_to_timespec(iap->ia_mtime);
-                       p = xdr_encode_nfstime4(p, &ts);
+                       p = xdr_encode_nfstime4(p, &iap->ia_mtime);
                } else
                        *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
        }
@@ -4065,17 +4062,17 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint
 }
 
 static __be32 *
-xdr_decode_nfstime4(__be32 *p, struct timespec *t)
+xdr_decode_nfstime4(__be32 *p, struct timespec64 *t)
 {
        __u64 sec;
 
        p = xdr_decode_hyper(p, &sec);
-       t-> tv_sec = (time_t)sec;
+       t-> tv_sec = sec;
        t->tv_nsec = be32_to_cpup(p++);
        return p;
 }
 
-static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
+static int decode_attr_time(struct xdr_stream *xdr, struct timespec64 *time)
 {
        __be32 *p;
 
@@ -4086,7 +4083,7 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
        return 0;
 }
 
-static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
+static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
 {
        int status = 0;
 
@@ -4104,7 +4101,7 @@ static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, str
        return status;
 }
 
-static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
+static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
 {
        int status = 0;
 
@@ -4123,7 +4120,7 @@ static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, s
 }
 
 static int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap,
-                                 struct timespec *time)
+                                 struct timespec64 *time)
 {
        int status = 0;
 
@@ -4186,7 +4183,7 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
        return status;
 }
 
-static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
+static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
 {
        int status = 0;
 
@@ -7581,6 +7578,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
        PROC42(CLONE,           enc_clone,              dec_clone),
        PROC42(COPY,            enc_copy,               dec_copy),
        PROC42(OFFLOAD_CANCEL,  enc_offload_cancel,     dec_offload_cancel),
+       PROC42(COPY_NOTIFY,     enc_copy_notify,        dec_copy_notify),
        PROC(LOOKUPP,           enc_lookupp,            dec_lookupp),
        PROC42(LAYOUTERROR,     enc_layouterror,        dec_layouterror),
 };
index 361cc10..f64a33d 100644 (file)
@@ -1065,6 +1065,39 @@ TRACE_EVENT(nfs_commit_done,
                )
 );
 
+TRACE_EVENT(nfs_fh_to_dentry,
+               TP_PROTO(
+                       const struct super_block *sb,
+                       const struct nfs_fh *fh,
+                       u64 fileid,
+                       int error
+               ),
+
+               TP_ARGS(sb, fh, fileid, error),
+
+               TP_STRUCT__entry(
+                       __field(int, error)
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+               ),
+
+               TP_fast_assign(
+                       __entry->error = error;
+                       __entry->dev = sb->s_dev;
+                       __entry->fileid = fileid;
+                       __entry->fhandle = nfs_fhandle_hash(fh);
+               ),
+
+               TP_printk(
+                       "error=%d fileid=%02x:%02x:%llu fhandle=0x%08x ",
+                       __entry->error,
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle
+               )
+);
+
 TRACE_DEFINE_ENUM(NFS_OK);
 TRACE_DEFINE_ENUM(NFSERR_PERM);
 TRACE_DEFINE_ENUM(NFSERR_NOENT);
index bb80034..cec3070 100644 (file)
@@ -2160,8 +2160,6 @@ out_unlock:
        return NULL;
 }
 
-extern const nfs4_stateid current_stateid;
-
 static void _lgopen_prepare_attached(struct nfs4_opendata *data,
                                     struct nfs_open_context *ctx)
 {
index a84df7d..8d8d04b 100644 (file)
@@ -1592,7 +1592,7 @@ static int nfs_parse_mount_options(char *raw,
                                        dfprintk(MOUNT, "NFS:   invalid "
                                                        "lookupcache argument\n");
                                        return 0;
-                       };
+                       }
                        break;
                case Opt_fscache_uniq:
                        if (nfs_get_option_str(args, &mnt->fscache_uniq))
@@ -1625,7 +1625,7 @@ static int nfs_parse_mount_options(char *raw,
                                dfprintk(MOUNT, "NFS:   invalid "
                                                "local_lock argument\n");
                                return 0;
-                       };
+                       }
                        break;
 
                /*
@@ -2585,7 +2585,7 @@ static void nfs_get_cache_cookie(struct super_block *sb,
                if (mnt_s->fscache_key) {
                        uniq = mnt_s->fscache_key->key.uniquifier;
                        ulen = mnt_s->fscache_key->key.uniq_len;
-               };
+               }
        } else
                return;
 
index 4f3390b..c489496 100644 (file)
@@ -121,8 +121,7 @@ static void nfs_netns_client_release(struct kobject *kobj)
                        struct nfs_netns_client,
                        kobject);
 
-       if (c->identifier)
-               kfree(c->identifier);
+       kfree(c->identifier);
        kfree(c);
 }
 
index 10cefb0..f2f8156 100644 (file)
@@ -73,7 +73,8 @@ config NFSD_V4
        select NFSD_V3
        select FS_POSIX_ACL
        select SUNRPC_GSS
-       select CRYPTO
+       select CRYPTO_MD5
+       select CRYPTO_SHA256
        select GRACE_PERIOD
        help
          This option enables support in your system's NFS server for
index ef55e9b..32a9bf2 100644 (file)
@@ -685,8 +685,6 @@ nfsd_file_cache_purge(struct net *net)
 void
 nfsd_file_cache_shutdown(void)
 {
-       LIST_HEAD(dispose);
-
        set_bit(NFSD_FILE_SHUTDOWN, &nfsd_file_lru_flags);
 
        lease_unregister_notifier(&nfsd_file_lease_notifier);
index 86e5658..195ab7a 100644 (file)
@@ -863,13 +863,11 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
                } else
                        dchild = dget(dparent);
        } else
-               dchild = lookup_one_len_unlocked(name, dparent, namlen);
+               dchild = lookup_positive_unlocked(name, dparent, namlen);
        if (IS_ERR(dchild))
                return rv;
        if (d_mountpoint(dchild))
                goto out;
-       if (d_really_is_negative(dchild))
-               goto out;
        if (dchild->d_inode->i_ino != ino)
                goto out;
        rv = fh_compose(fhp, exp, dchild, &cd->fh);
index 5241114..24534db 100644 (file)
@@ -826,6 +826,31 @@ static int max_cb_time(struct net *net)
        return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
 }
 
+static struct workqueue_struct *callback_wq;
+
+static bool nfsd4_queue_cb(struct nfsd4_callback *cb)
+{
+       return queue_work(callback_wq, &cb->cb_work);
+}
+
+static void nfsd41_cb_inflight_begin(struct nfs4_client *clp)
+{
+       atomic_inc(&clp->cl_cb_inflight);
+}
+
+static void nfsd41_cb_inflight_end(struct nfs4_client *clp)
+{
+
+       if (atomic_dec_and_test(&clp->cl_cb_inflight))
+               wake_up_var(&clp->cl_cb_inflight);
+}
+
+static void nfsd41_cb_inflight_wait_complete(struct nfs4_client *clp)
+{
+       wait_var_event(&clp->cl_cb_inflight,
+                       !atomic_read(&clp->cl_cb_inflight));
+}
+
 static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
 {
        if (clp->cl_minorversion == 0) {
@@ -937,14 +962,21 @@ static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
                clp->cl_cb_state = NFSD4_CB_UP;
 }
 
+static void nfsd4_cb_probe_release(void *calldata)
+{
+       struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
+
+       nfsd41_cb_inflight_end(clp);
+
+}
+
 static const struct rpc_call_ops nfsd4_cb_probe_ops = {
        /* XXX: release method to ensure we set the cb channel down if
         * necessary on early failure? */
        .rpc_call_done = nfsd4_cb_probe_done,
+       .rpc_release = nfsd4_cb_probe_release,
 };
 
-static struct workqueue_struct *callback_wq;
-
 /*
  * Poke the callback thread to process any updates to the callback
  * parameters, and send a null probe.
@@ -975,9 +1007,12 @@ void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
  * If the slot is available, then mark it busy.  Otherwise, set the
  * thread for sleeping on the callback RPC wait queue.
  */
-static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
+static bool nfsd41_cb_get_slot(struct nfsd4_callback *cb, struct rpc_task *task)
 {
-       if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
+       struct nfs4_client *clp = cb->cb_clp;
+
+       if (!cb->cb_holds_slot &&
+           test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
                rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
                /* Race breaker */
                if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
@@ -986,9 +1021,31 @@ static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
                }
                rpc_wake_up_queued_task(&clp->cl_cb_waitq, task);
        }
+       cb->cb_holds_slot = true;
        return true;
 }
 
+static void nfsd41_cb_release_slot(struct nfsd4_callback *cb)
+{
+       struct nfs4_client *clp = cb->cb_clp;
+
+       if (cb->cb_holds_slot) {
+               cb->cb_holds_slot = false;
+               clear_bit(0, &clp->cl_cb_slot_busy);
+               rpc_wake_up_next(&clp->cl_cb_waitq);
+       }
+}
+
+static void nfsd41_destroy_cb(struct nfsd4_callback *cb)
+{
+       struct nfs4_client *clp = cb->cb_clp;
+
+       nfsd41_cb_release_slot(cb);
+       if (cb->cb_ops && cb->cb_ops->release)
+               cb->cb_ops->release(cb);
+       nfsd41_cb_inflight_end(clp);
+}
+
 /*
  * TODO: cb_sequence should support referring call lists, cachethis, multiple
  * slots, and mark callback channel down on communication errors.
@@ -1005,11 +1062,8 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
         */
        cb->cb_seq_status = 1;
        cb->cb_status = 0;
-       if (minorversion) {
-               if (!cb->cb_holds_slot && !nfsd41_cb_get_slot(clp, task))
-                       return;
-               cb->cb_holds_slot = true;
-       }
+       if (minorversion && !nfsd41_cb_get_slot(cb, task))
+               return;
        rpc_call_start(task);
 }
 
@@ -1072,13 +1126,12 @@ static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback
                }
                break;
        default:
+               nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status);
                dprintk("%s: unprocessed error %d\n", __func__,
                        cb->cb_seq_status);
        }
 
-       cb->cb_holds_slot = false;
-       clear_bit(0, &clp->cl_cb_slot_busy);
-       rpc_wake_up_next(&clp->cl_cb_waitq);
+       nfsd41_cb_release_slot(cb);
        dprintk("%s: freed slot, new seqid=%d\n", __func__,
                clp->cl_cb_session->se_cb_seq_nr);
 
@@ -1091,8 +1144,10 @@ retry_nowait:
                ret = false;
        goto out;
 need_restart:
-       task->tk_status = 0;
-       cb->cb_need_restart = true;
+       if (!test_bit(NFSD4_CLIENT_CB_KILL, &clp->cl_flags)) {
+               task->tk_status = 0;
+               cb->cb_need_restart = true;
+       }
        return false;
 }
 
@@ -1134,9 +1189,9 @@ static void nfsd4_cb_release(void *calldata)
        struct nfsd4_callback *cb = calldata;
 
        if (cb->cb_need_restart)
-               nfsd4_run_cb(cb);
+               nfsd4_queue_cb(cb);
        else
-               cb->cb_ops->release(cb);
+               nfsd41_destroy_cb(cb);
 
 }
 
@@ -1170,6 +1225,7 @@ void nfsd4_shutdown_callback(struct nfs4_client *clp)
         */
        nfsd4_run_cb(&clp->cl_cb_null);
        flush_workqueue(callback_wq);
+       nfsd41_cb_inflight_wait_complete(clp);
 }
 
 /* requires cl_lock: */
@@ -1187,6 +1243,12 @@ static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp)
        return NULL;
 }
 
+/*
+ * Note there isn't a lot of locking in this code; instead we depend on
+ * the fact that it is run from the callback_wq, which won't run two
+ * work items at once.  So, for example, callback_wq handles all access
+ * of cl_cb_client and all calls to rpc_create or rpc_shutdown_client.
+ */
 static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
 {
        struct nfs4_cb_conn conn;
@@ -1255,8 +1317,7 @@ nfsd4_run_cb_work(struct work_struct *work)
        clnt = clp->cl_cb_client;
        if (!clnt) {
                /* Callback channel broken, or client killed; give up: */
-               if (cb->cb_ops && cb->cb_ops->release)
-                       cb->cb_ops->release(cb);
+               nfsd41_destroy_cb(cb);
                return;
        }
 
@@ -1265,6 +1326,7 @@ nfsd4_run_cb_work(struct work_struct *work)
         */
        if (!cb->cb_ops && clp->cl_minorversion) {
                clp->cl_cb_state = NFSD4_CB_UP;
+               nfsd41_destroy_cb(cb);
                return;
        }
 
@@ -1290,5 +1352,9 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
 
 void nfsd4_run_cb(struct nfsd4_callback *cb)
 {
-       queue_work(callback_wq, &cb->cb_work);
+       struct nfs4_client *clp = cb->cb_clp;
+
+       nfsd41_cb_inflight_begin(clp);
+       if (!nfsd4_queue_cb(cb))
+               nfsd41_cb_inflight_end(clp);
 }
index 4e3e77b..4798667 100644 (file)
@@ -1077,7 +1077,8 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                goto out;
 
        status = nfsd4_clone_file_range(src->nf_file, clone->cl_src_pos,
-                       dst->nf_file, clone->cl_dst_pos, clone->cl_count);
+                       dst->nf_file, clone->cl_dst_pos, clone->cl_count,
+                       EX_ISSYNC(cstate->current_fh.fh_export));
 
        nfsd_file_put(dst);
        nfsd_file_put(src);
@@ -1297,7 +1298,8 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 out:
        return status;
 out_err:
-       cleanup_async_copy(async_copy);
+       if (async_copy)
+               cleanup_async_copy(async_copy);
        goto out;
 }
 
index cdc75ad..2481e76 100644 (file)
@@ -1578,6 +1578,7 @@ nfsd4_cld_tracking_init(struct net *net)
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
        bool running;
        int retries = 10;
+       struct crypto_shash *tfm;
 
        status = nfs4_cld_state_init(net);
        if (status)
@@ -1586,11 +1587,6 @@ nfsd4_cld_tracking_init(struct net *net)
        status = __nfsd4_init_cld_pipe(net);
        if (status)
                goto err_shutdown;
-       nn->cld_net->cn_tfm = crypto_alloc_shash("sha256", 0, 0);
-       if (IS_ERR(nn->cld_net->cn_tfm)) {
-               status = PTR_ERR(nn->cld_net->cn_tfm);
-               goto err_remove;
-       }
 
        /*
         * rpc pipe upcalls take 30 seconds to time out, so we don't want to
@@ -1607,6 +1603,12 @@ nfsd4_cld_tracking_init(struct net *net)
                status = -ETIMEDOUT;
                goto err_remove;
        }
+       tfm = crypto_alloc_shash("sha256", 0, 0);
+       if (IS_ERR(tfm)) {
+               status = PTR_ERR(tfm);
+               goto err_remove;
+       }
+       nn->cld_net->cn_tfm = tfm;
 
        status = nfsd4_cld_get_version(nn);
        if (status == -EOPNOTSUPP)
@@ -1850,19 +1852,14 @@ nfsd4_umh_cltrack_upcall(char *cmd, char *arg, char *env0, char *env1)
 static char *
 bin_to_hex_dup(const unsigned char *src, int srclen)
 {
-       int i;
-       char *buf, *hex;
+       char *buf;
 
        /* +1 for terminating NULL */
-       buf = kmalloc((srclen * 2) + 1, GFP_KERNEL);
+       buf = kzalloc((srclen * 2) + 1, GFP_KERNEL);
        if (!buf)
                return buf;
 
-       hex = buf;
-       for (i = 0; i < srclen; i++) {
-               sprintf(hex, "%2.2x", *src++);
-               hex += 2;
-       }
+       bin2hex(buf, src, srclen);
        return buf;
 }
 
index c65aeaa..369e574 100644 (file)
@@ -2382,10 +2382,10 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
        access = bmap_to_share_mode(ols->st_access_bmap);
        deny   = bmap_to_share_mode(ols->st_deny_bmap);
 
-       seq_printf(s, "access: \%s\%s, ",
+       seq_printf(s, "access: %s%s, ",
                access & NFS4_SHARE_ACCESS_READ ? "r" : "-",
                access & NFS4_SHARE_ACCESS_WRITE ? "w" : "-");
-       seq_printf(s, "deny: \%s\%s, ",
+       seq_printf(s, "deny: %s%s, ",
                deny & NFS4_SHARE_ACCESS_READ ? "r" : "-",
                deny & NFS4_SHARE_ACCESS_WRITE ? "w" : "-");
 
@@ -3548,12 +3548,17 @@ static bool replay_matches_cache(struct svc_rqst *rqstp,
            (bool)seq->cachethis)
                return false;
        /*
-        * If there's an error than the reply can have fewer ops than
-        * the call.  But if we cached a reply with *more* ops than the
-        * call you're sending us now, then this new call is clearly not
-        * really a replay of the old one:
+        * If there's an error then the reply can have fewer ops than
+        * the call.
         */
-       if (slot->sl_opcnt < argp->opcnt)
+       if (slot->sl_opcnt < argp->opcnt && !slot->sl_status)
+               return false;
+       /*
+        * But if we cached a reply with *more* ops than the call you're
+        * sending us now, then this new call is clearly not really a
+        * replay of the old one:
+        */
+       if (slot->sl_opcnt > argp->opcnt)
                return false;
        /* This is the only check explicitly called by spec: */
        if (!same_creds(&rqstp->rq_cred, &slot->sl_cred))
index 533d0fc..d2dc4c0 100644 (file)
@@ -2991,18 +2991,9 @@ nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
        __be32 nfserr;
        int ignore_crossmnt = 0;
 
-       dentry = lookup_one_len_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
+       dentry = lookup_positive_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
        if (IS_ERR(dentry))
                return nfserrno(PTR_ERR(dentry));
-       if (d_really_is_negative(dentry)) {
-               /*
-                * we're not holding the i_mutex here, so there's
-                * a window where this directory entry could have gone
-                * away.
-                */
-               dput(dentry);
-               return nfserr_noent;
-       }
 
        exp_get(exp);
        /*
@@ -3461,7 +3452,6 @@ static __be32 nfsd4_encode_splice_read(
        struct xdr_stream *xdr = &resp->xdr;
        struct xdr_buf *buf = xdr->buf;
        u32 eof;
-       long len;
        int space_left;
        __be32 nfserr;
        __be32 *p = xdr->p - 2;
@@ -3470,7 +3460,6 @@ static __be32 nfsd4_encode_splice_read(
        if (xdr->end - xdr->p < 1)
                return nfserr_resource;
 
-       len = maxcount;
        nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
                                  file, read->rd_offset, &maxcount, &eof);
        read->rd_length = maxcount;
index af29475..57b93d9 100644 (file)
@@ -280,7 +280,8 @@ void                nfsd_lockd_shutdown(void);
 #define nfserr_union_notsupp           cpu_to_be32(NFS4ERR_UNION_NOTSUPP)
 #define nfserr_offload_denied          cpu_to_be32(NFS4ERR_OFFLOAD_DENIED)
 #define nfserr_wrong_lfs               cpu_to_be32(NFS4ERR_WRONG_LFS)
-#define nfserr_badlabel                cpu_to_be32(NFS4ERR_BADLABEL)
+#define nfserr_badlabel                        cpu_to_be32(NFS4ERR_BADLABEL)
+#define nfserr_file_open               cpu_to_be32(NFS4ERR_FILE_OPEN)
 
 /* error codes for internal use */
 /* if a request fails due to kmalloc failure, it gets dropped.
index fdf7ed4..e8bee8f 100644 (file)
@@ -95,12 +95,11 @@ static const struct svc_version *nfsd_acl_version[] = {
 
 #define NFSD_ACL_MINVERS            2
 #define NFSD_ACL_NRVERS                ARRAY_SIZE(nfsd_acl_version)
-static const struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS];
 
 static struct svc_program      nfsd_acl_program = {
        .pg_prog                = NFS_ACL_PROGRAM,
        .pg_nvers               = NFSD_ACL_NRVERS,
-       .pg_vers                = nfsd_acl_versions,
+       .pg_vers                = nfsd_acl_version,
        .pg_name                = "nfsacl",
        .pg_class               = "nfsd",
        .pg_stats               = &nfsd_acl_svcstats,
index 46f56af..d61b83b 100644 (file)
@@ -367,6 +367,7 @@ struct nfs4_client {
        struct net              *net;
        struct list_head        async_copies;   /* list of async copies */
        spinlock_t              async_lock;     /* lock for async copies */
+       atomic_t                cl_cb_inflight; /* Outstanding callbacks */
 };
 
 /* struct nfs4_client_reset
index bd0a385..c0dc491 100644 (file)
@@ -525,7 +525,7 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
 #endif
 
 __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
-               u64 dst_pos, u64 count)
+               u64 dst_pos, u64 count, bool sync)
 {
        loff_t cloned;
 
@@ -534,6 +534,12 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
                return nfserrno(cloned);
        if (count && cloned != count)
                return nfserrno(-EINVAL);
+       if (sync) {
+               loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX;
+               int status = vfs_fsync_range(dst, dst_pos, dst_end, 0);
+               if (status < 0)
+                       return nfserrno(status);
+       }
        return 0;
 }
 
@@ -1809,7 +1815,17 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 out_drop_write:
        fh_drop_write(fhp);
 out_nfserr:
-       err = nfserrno(host_err);
+       if (host_err == -EBUSY) {
+               /* name is mounted-on. There is no perfect
+                * error status.
+                */
+               if (nfsd_v4client(rqstp))
+                       err = nfserr_file_open;
+               else
+                       err = nfserr_acces;
+       } else {
+               err = nfserrno(host_err);
+       }
 out:
        return err;
 }
index a13fd9d..cc110a1 100644 (file)
@@ -56,7 +56,7 @@ __be32          nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
 __be32         nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
                                    struct file *, loff_t, loff_t, int);
 __be32         nfsd4_clone_file_range(struct file *, u64, struct file *,
-                       u64, u64);
+                                      u64, u64, bool);
 #endif /* CONFIG_NFSD_V4 */
 __be32         nfsd_create_locked(struct svc_rqst *, struct svc_fh *,
                                char *name, int len, struct iattr *attrs,
index a5612ab..c740159 100644 (file)
@@ -46,8 +46,9 @@ static int flush_racache(struct inode *inode)
  * Post and wait for the I/O upcall to finish
  */
 ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
-    loff_t *offset, struct iov_iter *iter, size_t total_size,
-    loff_t readahead_size, struct orangefs_write_range *wr, int *index_return)
+       loff_t *offset, struct iov_iter *iter, size_t total_size,
+       loff_t readahead_size, struct orangefs_write_range *wr,
+       int *index_return, struct file *file)
 {
        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
        struct orangefs_khandle *handle = &orangefs_inode->refn.khandle;
@@ -55,6 +56,8 @@ ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
        int buffer_index;
        ssize_t ret;
        size_t copy_amount;
+       int open_for_read;
+       int open_for_write;
 
        new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO);
        if (!new_op)
@@ -90,6 +93,38 @@ populate_shared_memory:
                new_op->upcall.uid = from_kuid(&init_user_ns, wr->uid);
                new_op->upcall.gid = from_kgid(&init_user_ns, wr->gid);
        }
+       /*
+        * Orangefs has no open, and orangefs checks file permissions
+        * on each file access. Posix requires that file permissions
+        * be checked on open and nowhere else. Orangefs-through-the-kernel
+        * needs to seem posix compliant.
+        *
+        * The VFS opens files, even if the filesystem provides no
+        * method. We can see if a file was successfully opened for
+        * read and or for write by looking at file->f_mode.
+        *
+        * When writes are flowing from the page cache, file is no
+        * longer available. We can trust the VFS to have checked
+        * file->f_mode before writing to the page cache.
+        *
+        * The mode of a file might change between when it is opened
+        * and IO commences, or it might be created with an arbitrary mode.
+        *
+        * We'll make sure we don't hit EACCES during the IO stage by
+        * using UID 0. Some of the time we have access without changing
+        * to UID 0 - how to check?
+        */
+       if (file) {
+               open_for_write = file->f_mode & FMODE_WRITE;
+               open_for_read = file->f_mode & FMODE_READ;
+       } else {
+               open_for_write = 1;
+               open_for_read = 0; /* not relevant? */
+       }
+       if ((type == ORANGEFS_IO_WRITE) && open_for_write)
+               new_op->upcall.uid = 0;
+       if ((type == ORANGEFS_IO_READ) && open_for_read)
+               new_op->upcall.uid = 0;
 
        gossip_debug(GOSSIP_FILE_DEBUG,
                     "%s(%pU): offset: %llu total_size: %zd\n",
index efb1219..961c0fd 100644 (file)
@@ -55,7 +55,7 @@ static int orangefs_writepage_locked(struct page *page,
        iov_iter_bvec(&iter, WRITE, &bv, 1, wlen);
 
        ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, wlen,
-           len, wr, NULL);
+           len, wr, NULL, NULL);
        if (ret < 0) {
                SetPageError(page);
                mapping_set_error(page->mapping, ret);
@@ -126,7 +126,7 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
        wr.uid = ow->uid;
        wr.gid = ow->gid;
        ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, ow->len,
-           0, &wr, NULL);
+           0, &wr, NULL, NULL);
        if (ret < 0) {
                for (i = 0; i < ow->npages; i++) {
                        SetPageError(ow->pages[i]);
@@ -311,7 +311,7 @@ static int orangefs_readpage(struct file *file, struct page *page)
        iov_iter_bvec(&iter, READ, &bv, 1, PAGE_SIZE);
 
        ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, &off, &iter,
-           read_size, inode->i_size, NULL, &buffer_index);
+           read_size, inode->i_size, NULL, &buffer_index, file);
        remaining = ret;
        /* this will only zero remaining unread portions of the page data */
        iov_iter_zero(~0U, &iter);
@@ -651,7 +651,7 @@ static ssize_t orangefs_direct_IO(struct kiocb *iocb,
                             (int)*offset);
 
                ret = wait_for_direct_io(type, inode, offset, iter,
-                               each_count, 0, NULL, NULL);
+                               each_count, 0, NULL, NULL, file);
                gossip_debug(GOSSIP_FILE_DEBUG,
                             "%s(%pU): return from wait_for_io:%d\n",
                             __func__,
index 34a6c99..ed67f39 100644 (file)
@@ -398,7 +398,8 @@ bool __is_daemon_in_service(void);
  */
 int orangefs_revalidate_mapping(struct inode *);
 ssize_t wait_for_direct_io(enum ORANGEFS_io_type, struct inode *, loff_t *,
-    struct iov_iter *, size_t, loff_t, struct orangefs_write_range *, int *);
+    struct iov_iter *, size_t, loff_t, struct orangefs_write_range *, int *,
+    struct file *);
 ssize_t do_readv_writev(enum ORANGEFS_io_type, struct file *, loff_t *,
     struct iov_iter *);
 
index b801c63..6220642 100644 (file)
@@ -227,13 +227,17 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
 struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper)
 {
        struct ovl_fh *fh;
-       int fh_type, fh_len, dwords;
-       void *buf;
+       int fh_type, dwords;
        int buflen = MAX_HANDLE_SZ;
        uuid_t *uuid = &real->d_sb->s_uuid;
+       int err;
 
-       buf = kmalloc(buflen, GFP_KERNEL);
-       if (!buf)
+       /* Make sure the real fid stays 32bit aligned */
+       BUILD_BUG_ON(OVL_FH_FID_OFFSET % 4);
+       BUILD_BUG_ON(MAX_HANDLE_SZ + OVL_FH_FID_OFFSET > 255);
+
+       fh = kzalloc(buflen + OVL_FH_FID_OFFSET, GFP_KERNEL);
+       if (!fh)
                return ERR_PTR(-ENOMEM);
 
        /*
@@ -242,27 +246,19 @@ struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper)
         * the price or reconnecting the dentry.
         */
        dwords = buflen >> 2;
-       fh_type = exportfs_encode_fh(real, buf, &dwords, 0);
+       fh_type = exportfs_encode_fh(real, (void *)fh->fb.fid, &dwords, 0);
        buflen = (dwords << 2);
 
-       fh = ERR_PTR(-EIO);
+       err = -EIO;
        if (WARN_ON(fh_type < 0) ||
            WARN_ON(buflen > MAX_HANDLE_SZ) ||
            WARN_ON(fh_type == FILEID_INVALID))
-               goto out;
+               goto out_err;
 
-       BUILD_BUG_ON(MAX_HANDLE_SZ + offsetof(struct ovl_fh, fid) > 255);
-       fh_len = offsetof(struct ovl_fh, fid) + buflen;
-       fh = kmalloc(fh_len, GFP_KERNEL);
-       if (!fh) {
-               fh = ERR_PTR(-ENOMEM);
-               goto out;
-       }
-
-       fh->version = OVL_FH_VERSION;
-       fh->magic = OVL_FH_MAGIC;
-       fh->type = fh_type;
-       fh->flags = OVL_FH_FLAG_CPU_ENDIAN;
+       fh->fb.version = OVL_FH_VERSION;
+       fh->fb.magic = OVL_FH_MAGIC;
+       fh->fb.type = fh_type;
+       fh->fb.flags = OVL_FH_FLAG_CPU_ENDIAN;
        /*
         * When we will want to decode an overlay dentry from this handle
         * and all layers are on the same fs, if we get a disconncted real
@@ -270,14 +266,15 @@ struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper)
         * it to upperdentry or to lowerstack is by checking this flag.
         */
        if (is_upper)
-               fh->flags |= OVL_FH_FLAG_PATH_UPPER;
-       fh->len = fh_len;
-       fh->uuid = *uuid;
-       memcpy(fh->fid, buf, buflen);
+               fh->fb.flags |= OVL_FH_FLAG_PATH_UPPER;
+       fh->fb.len = sizeof(fh->fb) + buflen;
+       fh->fb.uuid = *uuid;
 
-out:
-       kfree(buf);
        return fh;
+
+out_err:
+       kfree(fh);
+       return ERR_PTR(err);
 }
 
 int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
@@ -300,8 +297,8 @@ int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
        /*
         * Do not fail when upper doesn't support xattrs.
         */
-       err = ovl_check_setxattr(dentry, upper, OVL_XATTR_ORIGIN, fh,
-                                fh ? fh->len : 0, 0);
+       err = ovl_check_setxattr(dentry, upper, OVL_XATTR_ORIGIN, fh->buf,
+                                fh ? fh->fb.len : 0, 0);
        kfree(fh);
 
        return err;
@@ -317,7 +314,7 @@ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index)
        if (IS_ERR(fh))
                return PTR_ERR(fh);
 
-       err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh, fh->len, 0);
+       err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh->buf, fh->fb.len, 0);
 
        kfree(fh);
        return err;
index 702aa63..29abdb1 100644 (file)
@@ -1170,7 +1170,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
        if (newdentry == trap)
                goto out_dput;
 
-       if (WARN_ON(olddentry->d_inode == newdentry->d_inode))
+       if (olddentry->d_inode == newdentry->d_inode)
                goto out_dput;
 
        err = 0;
index 73c9775..70e5558 100644 (file)
@@ -211,10 +211,11 @@ static int ovl_check_encode_origin(struct dentry *dentry)
        return 1;
 }
 
-static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
+static int ovl_dentry_to_fid(struct dentry *dentry, u32 *fid, int buflen)
 {
        struct ovl_fh *fh = NULL;
        int err, enc_lower;
+       int len;
 
        /*
         * Check if we should encode a lower or upper file handle and maybe
@@ -231,11 +232,12 @@ static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
                return PTR_ERR(fh);
 
        err = -EOVERFLOW;
-       if (fh->len > buflen)
+       len = OVL_FH_LEN(fh);
+       if (len > buflen)
                goto fail;
 
-       memcpy(buf, (char *)fh, fh->len);
-       err = fh->len;
+       memcpy(fid, fh, len);
+       err = len;
 
 out:
        kfree(fh);
@@ -243,31 +245,16 @@ out:
 
 fail:
        pr_warn_ratelimited("overlayfs: failed to encode file handle (%pd2, err=%i, buflen=%d, len=%d, type=%d)\n",
-                           dentry, err, buflen, fh ? (int)fh->len : 0,
-                           fh ? fh->type : 0);
+                           dentry, err, buflen, fh ? (int)fh->fb.len : 0,
+                           fh ? fh->fb.type : 0);
        goto out;
 }
 
-static int ovl_dentry_to_fh(struct dentry *dentry, u32 *fid, int *max_len)
-{
-       int res, len = *max_len << 2;
-
-       res = ovl_d_to_fh(dentry, (char *)fid, len);
-       if (res <= 0)
-               return FILEID_INVALID;
-
-       len = res;
-
-       /* Round up to dwords */
-       *max_len = (len + 3) >> 2;
-       return OVL_FILEID;
-}
-
 static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len,
                         struct inode *parent)
 {
        struct dentry *dentry;
-       int type;
+       int bytes = *max_len << 2;
 
        /* TODO: encode connectable file handles */
        if (parent)
@@ -277,10 +264,14 @@ static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len,
        if (WARN_ON(!dentry))
                return FILEID_INVALID;
 
-       type = ovl_dentry_to_fh(dentry, fid, max_len);
-
+       bytes = ovl_dentry_to_fid(dentry, fid, bytes);
        dput(dentry);
-       return type;
+       if (bytes <= 0)
+               return FILEID_INVALID;
+
+       *max_len = bytes >> 2;
+
+       return OVL_FILEID_V1;
 }
 
 /*
@@ -777,24 +768,45 @@ out_err:
        goto out;
 }
 
+static struct ovl_fh *ovl_fid_to_fh(struct fid *fid, int buflen, int fh_type)
+{
+       struct ovl_fh *fh;
+
+       /* If on-wire inner fid is aligned - nothing to do */
+       if (fh_type == OVL_FILEID_V1)
+               return (struct ovl_fh *)fid;
+
+       if (fh_type != OVL_FILEID_V0)
+               return ERR_PTR(-EINVAL);
+
+       fh = kzalloc(buflen, GFP_KERNEL);
+       if (!fh)
+               return ERR_PTR(-ENOMEM);
+
+       /* Copy unaligned inner fh into aligned buffer */
+       memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET);
+       return fh;
+}
+
 static struct dentry *ovl_fh_to_dentry(struct super_block *sb, struct fid *fid,
                                       int fh_len, int fh_type)
 {
        struct dentry *dentry = NULL;
-       struct ovl_fh *fh = (struct ovl_fh *) fid;
+       struct ovl_fh *fh = NULL;
        int len = fh_len << 2;
        unsigned int flags = 0;
        int err;
 
-       err = -EINVAL;
-       if (fh_type != OVL_FILEID)
+       fh = ovl_fid_to_fh(fid, len, fh_type);
+       err = PTR_ERR(fh);
+       if (IS_ERR(fh))
                goto out_err;
 
        err = ovl_check_fh_len(fh, len);
        if (err)
                goto out_err;
 
-       flags = fh->flags;
+       flags = fh->fb.flags;
        dentry = (flags & OVL_FH_FLAG_PATH_UPPER) ?
                 ovl_upper_fh_to_d(sb, fh) :
                 ovl_lower_fh_to_d(sb, fh);
@@ -802,12 +814,18 @@ static struct dentry *ovl_fh_to_dentry(struct super_block *sb, struct fid *fid,
        if (IS_ERR(dentry) && err != -ESTALE)
                goto out_err;
 
+out:
+       /* We may have needed to re-align OVL_FILEID_V0 */
+       if (!IS_ERR_OR_NULL(fh) && fh != (void *)fid)
+               kfree(fh);
+
        return dentry;
 
 out_err:
        pr_warn_ratelimited("overlayfs: failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
-                           len, fh_type, flags, err);
-       return ERR_PTR(err);
+                           fh_len, fh_type, flags, err);
+       dentry = ERR_PTR(err);
+       goto out;
 }
 
 static struct dentry *ovl_fh_to_parent(struct super_block *sb, struct fid *fid,
index bc14781..b045cf1 100644 (file)
@@ -200,8 +200,14 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
                        if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) ||
                            (!ovl_verify_lower(dentry->d_sb) &&
                             (is_dir || lowerstat.nlink == 1))) {
-                               stat->ino = lowerstat.ino;
                                lower_layer = ovl_layer_lower(dentry);
+                               /*
+                                * Cannot use origin st_dev;st_ino because
+                                * origin inode content may differ from overlay
+                                * inode content.
+                                */
+                               if (samefs || lower_layer->fsid)
+                                       stat->ino = lowerstat.ino;
                        }
 
                        /*
index e9717c2..76ff663 100644 (file)
@@ -84,21 +84,21 @@ static int ovl_acceptable(void *ctx, struct dentry *dentry)
  * Return -ENODATA for "origin unknown".
  * Return <0 for an invalid file handle.
  */
-int ovl_check_fh_len(struct ovl_fh *fh, int fh_len)
+int ovl_check_fb_len(struct ovl_fb *fb, int fb_len)
 {
-       if (fh_len < sizeof(struct ovl_fh) || fh_len < fh->len)
+       if (fb_len < sizeof(struct ovl_fb) || fb_len < fb->len)
                return -EINVAL;
 
-       if (fh->magic != OVL_FH_MAGIC)
+       if (fb->magic != OVL_FH_MAGIC)
                return -EINVAL;
 
        /* Treat larger version and unknown flags as "origin unknown" */
-       if (fh->version > OVL_FH_VERSION || fh->flags & ~OVL_FH_FLAG_ALL)
+       if (fb->version > OVL_FH_VERSION || fb->flags & ~OVL_FH_FLAG_ALL)
                return -ENODATA;
 
        /* Treat endianness mismatch as "origin unknown" */
-       if (!(fh->flags & OVL_FH_FLAG_ANY_ENDIAN) &&
-           (fh->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN)
+       if (!(fb->flags & OVL_FH_FLAG_ANY_ENDIAN) &&
+           (fb->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN)
                return -ENODATA;
 
        return 0;
@@ -119,15 +119,15 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
        if (res == 0)
                return NULL;
 
-       fh = kzalloc(res, GFP_KERNEL);
+       fh = kzalloc(res + OVL_FH_WIRE_OFFSET, GFP_KERNEL);
        if (!fh)
                return ERR_PTR(-ENOMEM);
 
-       res = vfs_getxattr(dentry, name, fh, res);
+       res = vfs_getxattr(dentry, name, fh->buf, res);
        if (res < 0)
                goto fail;
 
-       err = ovl_check_fh_len(fh, res);
+       err = ovl_check_fb_len(&fh->fb, res);
        if (err < 0) {
                if (err == -ENODATA)
                        goto out;
@@ -158,12 +158,12 @@ struct dentry *ovl_decode_real_fh(struct ovl_fh *fh, struct vfsmount *mnt,
         * Make sure that the stored uuid matches the uuid of the lower
         * layer where file handle will be decoded.
         */
-       if (!uuid_equal(&fh->uuid, &mnt->mnt_sb->s_uuid))
+       if (!uuid_equal(&fh->fb.uuid, &mnt->mnt_sb->s_uuid))
                return NULL;
 
-       bytes = (fh->len - offsetof(struct ovl_fh, fid));
-       real = exportfs_decode_fh(mnt, (struct fid *)fh->fid,
-                                 bytes >> 2, (int)fh->type,
+       bytes = (fh->fb.len - offsetof(struct ovl_fb, fid));
+       real = exportfs_decode_fh(mnt, (struct fid *)fh->fb.fid,
+                                 bytes >> 2, (int)fh->fb.type,
                                  connected ? ovl_acceptable : NULL, mnt);
        if (IS_ERR(real)) {
                /*
@@ -173,7 +173,7 @@ struct dentry *ovl_decode_real_fh(struct ovl_fh *fh, struct vfsmount *mnt,
                 * index entries correctly.
                 */
                if (real == ERR_PTR(-ESTALE) &&
-                   !(fh->flags & OVL_FH_FLAG_PATH_UPPER))
+                   !(fh->fb.flags & OVL_FH_FLAG_PATH_UPPER))
                        real = NULL;
                return real;
        }
@@ -200,7 +200,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
        int err;
        bool last_element = !post[0];
 
-       this = lookup_one_len_unlocked(name, base, namelen);
+       this = lookup_positive_unlocked(name, base, namelen);
        if (IS_ERR(this)) {
                err = PTR_ERR(this);
                this = NULL;
@@ -208,8 +208,6 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
                        goto out;
                goto out_err;
        }
-       if (!this->d_inode)
-               goto put_and_out;
 
        if (ovl_dentry_weird(this)) {
                /* Don't support traversing automounts and other weirdness */
@@ -325,6 +323,14 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
        int i;
 
        for (i = 0; i < ofs->numlower; i++) {
+               /*
+                * If lower fs uuid is not unique among lower fs we cannot match
+                * fh->uuid to layer.
+                */
+               if (ofs->lower_layers[i].fsid &&
+                   ofs->lower_layers[i].fs->bad_uuid)
+                       continue;
+
                origin = ovl_decode_real_fh(fh, ofs->lower_layers[i].mnt,
                                            connected);
                if (origin)
@@ -402,7 +408,7 @@ static int ovl_verify_fh(struct dentry *dentry, const char *name,
        if (IS_ERR(ofh))
                return PTR_ERR(ofh);
 
-       if (fh->len != ofh->len || memcmp(fh, ofh, fh->len))
+       if (fh->fb.len != ofh->fb.len || memcmp(&fh->fb, &ofh->fb, fh->fb.len))
                err = -ESTALE;
 
        kfree(ofh);
@@ -433,7 +439,7 @@ int ovl_verify_set_fh(struct dentry *dentry, const char *name,
 
        err = ovl_verify_fh(dentry, name, fh);
        if (set && err == -ENODATA)
-               err = ovl_do_setxattr(dentry, name, fh, fh->len, 0);
+               err = ovl_do_setxattr(dentry, name, fh->buf, fh->fb.len, 0);
        if (err)
                goto fail;
 
@@ -507,20 +513,20 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
                goto fail;
 
        err = -EINVAL;
-       if (index->d_name.len < sizeof(struct ovl_fh)*2)
+       if (index->d_name.len < sizeof(struct ovl_fb)*2)
                goto fail;
 
        err = -ENOMEM;
        len = index->d_name.len / 2;
-       fh = kzalloc(len, GFP_KERNEL);
+       fh = kzalloc(len + OVL_FH_WIRE_OFFSET, GFP_KERNEL);
        if (!fh)
                goto fail;
 
        err = -EINVAL;
-       if (hex2bin((u8 *)fh, index->d_name.name, len))
+       if (hex2bin(fh->buf, index->d_name.name, len))
                goto fail;
 
-       err = ovl_check_fh_len(fh, len);
+       err = ovl_check_fb_len(&fh->fb, len);
        if (err)
                goto fail;
 
@@ -599,11 +605,11 @@ static int ovl_get_index_name_fh(struct ovl_fh *fh, struct qstr *name)
 {
        char *n, *s;
 
-       n = kcalloc(fh->len, 2, GFP_KERNEL);
+       n = kcalloc(fh->fb.len, 2, GFP_KERNEL);
        if (!n)
                return -ENOMEM;
 
-       s  = bin2hex(n, fh, fh->len);
+       s  = bin2hex(n, fh->buf, fh->fb.len);
        *name = (struct qstr) QSTR_INIT(n, s - n);
 
        return 0;
@@ -651,7 +657,7 @@ struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh)
        if (err)
                return ERR_PTR(err);
 
-       index = lookup_one_len_unlocked(name.name, ofs->indexdir, name.len);
+       index = lookup_positive_unlocked(name.name, ofs->indexdir, name.len);
        kfree(name.name);
        if (IS_ERR(index)) {
                if (PTR_ERR(index) == -ENOENT)
@@ -659,9 +665,7 @@ struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh)
                return index;
        }
 
-       if (d_is_negative(index))
-               err = 0;
-       else if (ovl_is_whiteout(index))
+       if (ovl_is_whiteout(index))
                err = -ESTALE;
        else if (ovl_dentry_weird(index))
                err = -EIO;
@@ -685,7 +689,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
        if (err)
                return ERR_PTR(err);
 
-       index = lookup_one_len_unlocked(name.name, ofs->indexdir, name.len);
+       index = lookup_positive_unlocked(name.name, ofs->indexdir, name.len);
        if (IS_ERR(index)) {
                err = PTR_ERR(index);
                if (err == -ENOENT) {
@@ -700,9 +704,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
        }
 
        inode = d_inode(index);
-       if (d_is_negative(index)) {
-               goto out_dput;
-       } else if (ovl_is_whiteout(index) && !verify) {
+       if (ovl_is_whiteout(index) && !verify) {
                /*
                 * When index lookup is called with !verify for decoding an
                 * overlay file handle, a whiteout index implies that decode
@@ -1131,7 +1133,7 @@ bool ovl_lower_positive(struct dentry *dentry)
                struct dentry *this;
                struct dentry *lowerdir = poe->lowerstack[i].dentry;
 
-               this = lookup_one_len_unlocked(name->name, lowerdir,
+               this = lookup_positive_unlocked(name->name, lowerdir,
                                               name->len);
                if (IS_ERR(this)) {
                        switch (PTR_ERR(this)) {
@@ -1148,10 +1150,8 @@ bool ovl_lower_positive(struct dentry *dentry)
                                break;
                        }
                } else {
-                       if (this->d_inode) {
-                               positive = !ovl_is_whiteout(this);
-                               done = true;
-                       }
+                       positive = !ovl_is_whiteout(this);
+                       done = true;
                        dput(this);
                }
        }
index 6934bcf..f283b1d 100644 (file)
@@ -71,20 +71,36 @@ enum ovl_entry_flag {
 #error Endianness not defined
 #endif
 
-/* The type returned by overlay exportfs ops when encoding an ovl_fh handle */
-#define OVL_FILEID     0xfb
+/* The type used to be returned by overlay exportfs for misaligned fid */
+#define OVL_FILEID_V0  0xfb
+/* The type returned by overlay exportfs for 32bit aligned fid */
+#define OVL_FILEID_V1  0xf8
 
-/* On-disk and in-memeory format for redirect by file handle */
-struct ovl_fh {
+/* On-disk format for "origin" file handle */
+struct ovl_fb {
        u8 version;     /* 0 */
        u8 magic;       /* 0xfb */
        u8 len;         /* size of this header + size of fid */
        u8 flags;       /* OVL_FH_FLAG_* */
        u8 type;        /* fid_type of fid */
        uuid_t uuid;    /* uuid of filesystem */
-       u8 fid[0];      /* file identifier */
+       u32 fid[0];     /* file identifier should be 32bit aligned in-memory */
 } __packed;
 
+/* In-memory and on-wire format for overlay file handle */
+struct ovl_fh {
+       u8 padding[3];  /* make sure fb.fid is 32bit aligned */
+       union {
+               struct ovl_fb fb;
+               u8 buf[0];
+       };
+} __packed;
+
+#define OVL_FH_WIRE_OFFSET     offsetof(struct ovl_fh, fb)
+#define OVL_FH_LEN(fh)         (OVL_FH_WIRE_OFFSET + (fh)->fb.len)
+#define OVL_FH_FID_OFFSET      (OVL_FH_WIRE_OFFSET + \
+                                offsetof(struct ovl_fb, fid))
+
 static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry)
 {
        int err = vfs_rmdir(dir, dentry);
@@ -302,7 +318,13 @@ static inline void ovl_inode_unlock(struct inode *inode)
 
 
 /* namei.c */
-int ovl_check_fh_len(struct ovl_fh *fh, int fh_len);
+int ovl_check_fb_len(struct ovl_fb *fb, int fb_len);
+
+static inline int ovl_check_fh_len(struct ovl_fh *fh, int fh_len)
+{
+       return ovl_check_fb_len(&fh->fb, fh_len - OVL_FH_WIRE_OFFSET);
+}
+
 struct dentry *ovl_decode_real_fh(struct ovl_fh *fh, struct vfsmount *mnt,
                                  bool connected);
 int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
index a827928..28348c4 100644 (file)
@@ -22,6 +22,8 @@ struct ovl_config {
 struct ovl_sb {
        struct super_block *sb;
        dev_t pseudo_dev;
+       /* Unusable (conflicting) uuid */
+       bool bad_uuid;
 };
 
 struct ovl_layer {
index afbcb11..7621ff1 100644 (file)
@@ -1255,7 +1255,7 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid)
 {
        unsigned int i;
 
-       if (!ofs->config.nfs_export && !(ofs->config.index && ofs->upper_mnt))
+       if (!ofs->config.nfs_export && !ofs->upper_mnt)
                return true;
 
        for (i = 0; i < ofs->numlowerfs; i++) {
@@ -1263,9 +1263,13 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid)
                 * We use uuid to associate an overlay lower file handle with a
                 * lower layer, so we can accept lower fs with null uuid as long
                 * as all lower layers with null uuid are on the same fs.
+                * if we detect multiple lower fs with the same uuid, we
+                * disable lower file handle decoding on all of them.
                 */
-               if (uuid_equal(&ofs->lower_fs[i].sb->s_uuid, uuid))
+               if (uuid_equal(&ofs->lower_fs[i].sb->s_uuid, uuid)) {
+                       ofs->lower_fs[i].bad_uuid = true;
                        return false;
+               }
        }
        return true;
 }
@@ -1277,6 +1281,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
        unsigned int i;
        dev_t dev;
        int err;
+       bool bad_uuid = false;
 
        /* fsid 0 is reserved for upper fs even with non upper overlay */
        if (ofs->upper_mnt && ofs->upper_mnt->mnt_sb == sb)
@@ -1288,11 +1293,15 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
        }
 
        if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) {
-               ofs->config.index = false;
-               ofs->config.nfs_export = false;
-               pr_warn("overlayfs: %s uuid detected in lower fs '%pd2', falling back to index=off,nfs_export=off.\n",
-                       uuid_is_null(&sb->s_uuid) ? "null" : "conflicting",
-                       path->dentry);
+               bad_uuid = true;
+               if (ofs->config.index || ofs->config.nfs_export) {
+                       ofs->config.index = false;
+                       ofs->config.nfs_export = false;
+                       pr_warn("overlayfs: %s uuid detected in lower fs '%pd2', falling back to index=off,nfs_export=off.\n",
+                               uuid_is_null(&sb->s_uuid) ? "null" :
+                                                           "conflicting",
+                               path->dentry);
+               }
        }
 
        err = get_anon_bdev(&dev);
@@ -1303,6 +1312,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
 
        ofs->lower_fs[ofs->numlowerfs].sb = sb;
        ofs->lower_fs[ofs->numlowerfs].pseudo_dev = dev;
+       ofs->lower_fs[ofs->numlowerfs].bad_uuid = bad_uuid;
        ofs->numlowerfs++;
 
        return ofs->numlowerfs;
index 648ce44..04d004e 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -270,22 +270,41 @@ static bool pipe_buf_can_merge(struct pipe_buffer *buf)
        return buf->ops == &anon_pipe_buf_ops;
 }
 
+/* Done while waiting without holding the pipe lock - thus the READ_ONCE() */
+static inline bool pipe_readable(const struct pipe_inode_info *pipe)
+{
+       unsigned int head = READ_ONCE(pipe->head);
+       unsigned int tail = READ_ONCE(pipe->tail);
+       unsigned int writers = READ_ONCE(pipe->writers);
+
+       return !pipe_empty(head, tail) || !writers;
+}
+
 static ssize_t
 pipe_read(struct kiocb *iocb, struct iov_iter *to)
 {
        size_t total_len = iov_iter_count(to);
        struct file *filp = iocb->ki_filp;
        struct pipe_inode_info *pipe = filp->private_data;
-       int do_wakeup;
+       bool was_full;
        ssize_t ret;
 
        /* Null read succeeds. */
        if (unlikely(total_len == 0))
                return 0;
 
-       do_wakeup = 0;
        ret = 0;
        __pipe_lock(pipe);
+
+       /*
+        * We only wake up writers if the pipe was full when we started
+        * reading in order to avoid unnecessary wakeups.
+        *
+        * But when we do wake up writers, we do so using a sync wakeup
+        * (WF_SYNC), because we want them to get going and generate more
+        * data for us.
+        */
+       was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
        for (;;) {
                unsigned int head = pipe->head;
                unsigned int tail = pipe->tail;
@@ -324,19 +343,11 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
                        }
 
                        if (!buf->len) {
-                               bool wake;
                                pipe_buf_release(pipe, buf);
                                spin_lock_irq(&pipe->wait.lock);
                                tail++;
                                pipe->tail = tail;
-                               do_wakeup = 1;
-                               wake = head - (tail - 1) == pipe->max_usage / 2;
-                               if (wake)
-                                       wake_up_locked_poll(
-                                               &pipe->wait, EPOLLOUT | EPOLLWRNORM);
                                spin_unlock_irq(&pipe->wait.lock);
-                               if (wake)
-                                       kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
                        }
                        total_len -= chars;
                        if (!total_len)
@@ -347,31 +358,52 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
 
                if (!pipe->writers)
                        break;
-               if (!pipe->waiting_writers) {
-                       /* syscall merging: Usually we must not sleep
-                        * if O_NONBLOCK is set, or if we got some data.
-                        * But if a writer sleeps in kernel space, then
-                        * we can wait for that data without violating POSIX.
-                        */
-                       if (ret)
-                               break;
-                       if (filp->f_flags & O_NONBLOCK) {
-                               ret = -EAGAIN;
-                               break;
-                       }
-               }
-               if (signal_pending(current)) {
-                       if (!ret)
-                               ret = -ERESTARTSYS;
+               if (ret)
+                       break;
+               if (filp->f_flags & O_NONBLOCK) {
+                       ret = -EAGAIN;
                        break;
                }
-               pipe_wait(pipe);
+               __pipe_unlock(pipe);
+
+               /*
+                * We only get here if we didn't actually read anything.
+                *
+                * However, we could have seen (and removed) a zero-sized
+                * pipe buffer, and might have made space in the buffers
+                * that way.
+                *
+                * You can't make zero-sized pipe buffers by doing an empty
+                * write (not even in packet mode), but they can happen if
+                * the writer gets an EFAULT when trying to fill a buffer
+                * that already got allocated and inserted in the buffer
+                * array.
+                *
+                * So we still need to wake up any pending writers in the
+                * _very_ unlikely case that the pipe was full, but we got
+                * no data.
+                */
+               if (unlikely(was_full)) {
+                       wake_up_interruptible_sync_poll(&pipe->wait, EPOLLOUT | EPOLLWRNORM);
+                       kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
+               }
+
+               /*
+                * But because we didn't read anything, at this point we can
+                * just return directly with -ERESTARTSYS if we're interrupted,
+                * since we've done any required wakeups and there's no need
+                * to mark anything accessed. And we've dropped the lock.
+                */
+               if (wait_event_interruptible(pipe->wait, pipe_readable(pipe)) < 0)
+                       return -ERESTARTSYS;
+
+               __pipe_lock(pipe);
+               was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
        }
        __pipe_unlock(pipe);
 
-       /* Signal writers asynchronously that there is more room. */
-       if (do_wakeup) {
-               wake_up_interruptible_poll(&pipe->wait, EPOLLOUT | EPOLLWRNORM);
+       if (was_full) {
+               wake_up_interruptible_sync_poll(&pipe->wait, EPOLLOUT | EPOLLWRNORM);
                kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
        }
        if (ret > 0)
@@ -384,16 +416,27 @@ static inline int is_packetized(struct file *file)
        return (file->f_flags & O_DIRECT) != 0;
 }
 
+/* Done while waiting without holding the pipe lock - thus the READ_ONCE() */
+static inline bool pipe_writable(const struct pipe_inode_info *pipe)
+{
+       unsigned int head = READ_ONCE(pipe->head);
+       unsigned int tail = READ_ONCE(pipe->tail);
+       unsigned int max_usage = READ_ONCE(pipe->max_usage);
+
+       return !pipe_full(head, tail, max_usage) ||
+               !READ_ONCE(pipe->readers);
+}
+
 static ssize_t
 pipe_write(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *filp = iocb->ki_filp;
        struct pipe_inode_info *pipe = filp->private_data;
-       unsigned int head, max_usage, mask;
+       unsigned int head;
        ssize_t ret = 0;
-       int do_wakeup = 0;
        size_t total_len = iov_iter_count(from);
        ssize_t chars;
+       bool was_empty = false;
 
        /* Null write succeeds. */
        if (unlikely(total_len == 0))
@@ -407,13 +450,22 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                goto out;
        }
 
+       /*
+        * Only wake up if the pipe started out empty, since
+        * otherwise there should be no readers waiting.
+        *
+        * If it wasn't empty we try to merge new data into
+        * the last buffer.
+        *
+        * That naturally merges small writes, but it also
+        * page-aligs the rest of the writes for large writes
+        * spanning multiple pages.
+        */
        head = pipe->head;
-       max_usage = pipe->max_usage;
-       mask = pipe->ring_size - 1;
-
-       /* We try to merge small writes */
-       chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
-       if (!pipe_empty(head, pipe->tail) && chars != 0) {
+       was_empty = pipe_empty(head, pipe->tail);
+       chars = total_len & (PAGE_SIZE-1);
+       if (chars && !was_empty) {
+               unsigned int mask = pipe->ring_size - 1;
                struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask];
                int offset = buf->offset + buf->len;
 
@@ -427,7 +479,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                                ret = -EFAULT;
                                goto out;
                        }
-                       do_wakeup = 1;
+
                        buf->len += ret;
                        if (!iov_iter_count(from))
                                goto out;
@@ -443,7 +495,8 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                }
 
                head = pipe->head;
-               if (!pipe_full(head, pipe->tail, max_usage)) {
+               if (!pipe_full(head, pipe->tail, pipe->max_usage)) {
+                       unsigned int mask = pipe->ring_size - 1;
                        struct pipe_buffer *buf = &pipe->bufs[head & mask];
                        struct page *page = pipe->tmp_page;
                        int copied;
@@ -465,23 +518,13 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                        spin_lock_irq(&pipe->wait.lock);
 
                        head = pipe->head;
-                       if (pipe_full(head, pipe->tail, max_usage)) {
+                       if (pipe_full(head, pipe->tail, pipe->max_usage)) {
                                spin_unlock_irq(&pipe->wait.lock);
                                continue;
                        }
 
                        pipe->head = head + 1;
-
-                       /* Always wake up, even if the copy fails. Otherwise
-                        * we lock up (O_NONBLOCK-)readers that sleep due to
-                        * syscall merging.
-                        * FIXME! Is this really true?
-                        */
-                       wake_up_locked_poll(
-                               &pipe->wait, EPOLLIN | EPOLLRDNORM);
-
                        spin_unlock_irq(&pipe->wait.lock);
-                       kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 
                        /* Insert it into the buffer array */
                        buf = &pipe->bufs[head & mask];
@@ -510,7 +553,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                                break;
                }
 
-               if (!pipe_full(head, pipe->tail, max_usage))
+               if (!pipe_full(head, pipe->tail, pipe->max_usage))
                        continue;
 
                /* Wait for buffer space to become available. */
@@ -524,14 +567,36 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                                ret = -ERESTARTSYS;
                        break;
                }
-               pipe->waiting_writers++;
-               pipe_wait(pipe);
-               pipe->waiting_writers--;
+
+               /*
+                * We're going to release the pipe lock and wait for more
+                * space. We wake up any readers if necessary, and then
+                * after waiting we need to re-check whether the pipe
+                * become empty while we dropped the lock.
+                */
+               __pipe_unlock(pipe);
+               if (was_empty) {
+                       wake_up_interruptible_sync_poll(&pipe->wait, EPOLLIN | EPOLLRDNORM);
+                       kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
+               }
+               wait_event_interruptible(pipe->wait, pipe_writable(pipe));
+               __pipe_lock(pipe);
+               was_empty = pipe_empty(head, pipe->tail);
        }
 out:
        __pipe_unlock(pipe);
-       if (do_wakeup) {
-               wake_up_interruptible_poll(&pipe->wait, EPOLLIN | EPOLLRDNORM);
+
+       /*
+        * If we do do a wakeup event, we do a 'sync' wakeup, because we
+        * want the reader to start processing things asap, rather than
+        * leave the data pending.
+        *
+        * This is particularly important for small writes, because of
+        * how (for example) the GNU make jobserver uses small writes to
+        * wake up pending jobs
+        */
+       if (was_empty) {
+               wake_up_interruptible_sync_poll(&pipe->wait, EPOLLIN | EPOLLRDNORM);
                kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
        }
        if (ret > 0 && sb_start_write_trylock(file_inode(filp)->i_sb)) {
@@ -574,14 +639,24 @@ pipe_poll(struct file *filp, poll_table *wait)
 {
        __poll_t mask;
        struct pipe_inode_info *pipe = filp->private_data;
-       unsigned int head = READ_ONCE(pipe->head);
-       unsigned int tail = READ_ONCE(pipe->tail);
+       unsigned int head, tail;
 
+       /*
+        * Reading only -- no need for acquiring the semaphore.
+        *
+        * But because this is racy, the code has to add the
+        * entry to the poll table _first_ ..
+        */
        poll_wait(filp, &pipe->wait, wait);
 
-       BUG_ON(pipe_occupancy(head, tail) > pipe->ring_size);
+       /*
+        * .. and only then can you do the racy tests. That way,
+        * if something changes and you got it wrong, the poll
+        * table entry will wake you up and fix it.
+        */
+       head = READ_ONCE(pipe->head);
+       tail = READ_ONCE(pipe->tail);
 
-       /* Reading only -- no need for acquiring the semaphore.  */
        mask = 0;
        if (filp->f_mode & FMODE_READ) {
                if (!pipe_empty(head, tail))
@@ -1176,6 +1251,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
        pipe->max_usage = nr_slots;
        pipe->tail = tail;
        pipe->head = head;
+       wake_up_interruptible_all(&pipe->wait);
        return pipe->max_usage * PAGE_SIZE;
 
 out_revert_acct:
index cb5629b..733881a 100644 (file)
@@ -42,8 +42,8 @@ config PROC_VMCORE
        bool "/proc/vmcore support"
        depends on PROC_FS && CRASH_DUMP
        default y
-        help
-        Exports the dump image of crashed kernel in ELF format.
+       help
+         Exports the dump image of crashed kernel in ELF format.
 
 config PROC_VMCORE_DEVICE_DUMP
        bool "Device Hardware/Firmware Log Collection"
@@ -72,7 +72,7 @@ config PROC_SYSCTL
          a recompile of the kernel or reboot of the system.  The primary
          interface is through /proc/sys.  If you say Y here a tree of
          modifiable sysctl entries will be generated beneath the
-          /proc/sys directory. They are explained in the files
+         /proc/sys directory. They are explained in the files
          in <file:Documentation/admin-guide/sysctl/>.  Note that enabling this
          option will enlarge the kernel by at least 8 KB.
 
@@ -88,7 +88,7 @@ config PROC_PAGE_MONITOR
          Various /proc files exist to monitor process memory utilization:
          /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
          /proc/kpagecount, and /proc/kpageflags. Disabling these
-          interfaces will reduce the size of the kernel by approximately 4kb.
+         interfaces will reduce the size of the kernel by approximately 4kb.
 
 config PROC_CHILDREN
        bool "Include /proc/<pid>/task/<tid>/children file"
index 64e9ee1..074e958 100644 (file)
@@ -138,8 +138,12 @@ static int proc_getattr(const struct path *path, struct kstat *stat,
 {
        struct inode *inode = d_inode(path->dentry);
        struct proc_dir_entry *de = PDE(inode);
-       if (de && de->nlink)
-               set_nlink(inode, de->nlink);
+       if (de) {
+               nlink_t nlink = READ_ONCE(de->nlink);
+               if (nlink > 0) {
+                       set_nlink(inode, nlink);
+               }
+       }
 
        generic_fillattr(inode, stat);
        return 0;
@@ -159,7 +163,6 @@ static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
 {
        const char              *cp = name, *next;
        struct proc_dir_entry   *de;
-       unsigned int            len;
 
        de = *ret;
        if (!de)
@@ -170,13 +173,12 @@ static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
                if (!next)
                        break;
 
-               len = next - cp;
-               de = pde_subdir_find(de, cp, len);
+               de = pde_subdir_find(de, cp, next - cp);
                if (!de) {
                        WARN(1, "name '%s'\n", name);
                        return -ENOENT;
                }
-               cp += len + 1;
+               cp = next + 1;
        }
        *residual = cp;
        *ret = de;
@@ -362,6 +364,7 @@ struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
                write_unlock(&proc_subdir_lock);
                goto out_free_inum;
        }
+       dir->nlink++;
        write_unlock(&proc_subdir_lock);
 
        return dp;
@@ -472,10 +475,7 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
                ent->data = data;
                ent->proc_fops = &proc_dir_operations;
                ent->proc_iops = &proc_dir_inode_operations;
-               parent->nlink++;
                ent = proc_register(parent, ent);
-               if (!ent)
-                       parent->nlink--;
        }
        return ent;
 }
@@ -505,10 +505,7 @@ struct proc_dir_entry *proc_create_mount_point(const char *name)
                ent->data = NULL;
                ent->proc_fops = NULL;
                ent->proc_iops = NULL;
-               parent->nlink++;
                ent = proc_register(parent, ent);
-               if (!ent)
-                       parent->nlink--;
        }
        return ent;
 }
@@ -666,8 +663,12 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
        len = strlen(fn);
 
        de = pde_subdir_find(parent, fn, len);
-       if (de)
+       if (de) {
                rb_erase(&de->subdir_node, &parent->subdir);
+               if (S_ISDIR(de->mode)) {
+                       parent->nlink--;
+               }
+       }
        write_unlock(&proc_subdir_lock);
        if (!de) {
                WARN(1, "name '%s'\n", name);
@@ -676,9 +677,6 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
 
        proc_entry_rundown(de);
 
-       if (S_ISDIR(de->mode))
-               parent->nlink--;
-       de->nlink = 0;
        WARN(pde_subdir_first(de),
             "%s: removing non-empty directory '%s/%s', leaking at least '%s'\n",
             __func__, de->parent->name, de->name, pde_subdir_first(de)->name);
@@ -714,13 +712,12 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
                        de = next;
                        continue;
                }
-               write_unlock(&proc_subdir_lock);
-
-               proc_entry_rundown(de);
                next = de->parent;
                if (S_ISDIR(de->mode))
                        next->nlink--;
-               de->nlink = 0;
+               write_unlock(&proc_subdir_lock);
+
+               proc_entry_rundown(de);
                if (de == root)
                        break;
                pde_put(de);
index cd0c8d5..0f3b557 100644 (file)
@@ -197,8 +197,8 @@ extern ssize_t proc_simple_write(struct file *, const char __user *, size_t, lof
  * inode.c
  */
 struct pde_opener {
-       struct file *file;
        struct list_head lh;
+       struct file *file;
        bool closing;
        struct completion *c;
 } __randomize_layout;
index 4639d53..b0688c0 100644 (file)
@@ -2487,21 +2487,15 @@ int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
        struct dentry *dentry;
        int error;
 
-       dentry = lookup_one_len_unlocked(qf_name, sb->s_root, strlen(qf_name));
+       dentry = lookup_positive_unlocked(qf_name, sb->s_root, strlen(qf_name));
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
 
-       if (d_really_is_negative(dentry)) {
-               error = -ENOENT;
-               goto out;
-       }
-
        error = security_quota_on(dentry);
        if (!error)
                error = dquot_load_quota_inode(d_inode(dentry), type, format_id,
                                DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
 
-out:
        dput(dentry);
        return error;
 }
index f2400ce..3009652 100644 (file)
@@ -495,7 +495,7 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des
        unsigned int mask = pipe->ring_size - 1;
        int ret;
 
-       while (!pipe_empty(tail, head)) {
+       while (!pipe_empty(head, tail)) {
                struct pipe_buffer *buf = &pipe->bufs[tail & mask];
 
                sd->len = buf->len;
@@ -559,7 +559,7 @@ static int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_des
                if (!pipe->writers)
                        return 0;
 
-               if (!pipe->waiting_writers && sd->num_spliced)
+               if (sd->num_spliced)
                        return 0;
 
                if (sd->flags & SPLICE_F_NONBLOCK)
@@ -711,9 +711,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
        splice_from_pipe_begin(&sd);
        while (sd.total_len) {
                struct iov_iter from;
-               unsigned int head = pipe->head;
-               unsigned int tail = pipe->tail;
-               unsigned int mask = pipe->ring_size - 1;
+               unsigned int head, tail, mask;
                size_t left;
                int n;
 
@@ -732,6 +730,10 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                        }
                }
 
+               head = pipe->head;
+               tail = pipe->tail;
+               mask = pipe->ring_size - 1;
+
                /* build the vector */
                left = sd.total_len;
                for (n = 0; !pipe_empty(head, tail) && left && n < nbufs; tail++, n++) {
@@ -1096,9 +1098,7 @@ static int wait_for_space(struct pipe_inode_info *pipe, unsigned flags)
                        return -EAGAIN;
                if (signal_pending(current))
                        return -ERESTARTSYS;
-               pipe->waiting_writers++;
                pipe_wait(pipe);
-               pipe->waiting_writers--;
        }
 }
 
@@ -1480,11 +1480,9 @@ static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
                }
                if (!pipe->writers)
                        break;
-               if (!pipe->waiting_writers) {
-                       if (flags & SPLICE_F_NONBLOCK) {
-                               ret = -EAGAIN;
-                               break;
-                       }
+               if (flags & SPLICE_F_NONBLOCK) {
+                       ret = -EAGAIN;
+                       break;
                }
                pipe_wait(pipe);
        }
@@ -1525,9 +1523,7 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
                        ret = -ERESTARTSYS;
                        break;
                }
-               pipe->waiting_writers++;
                pipe_wait(pipe);
-               pipe->waiting_writers--;
        }
 
        pipe_unlock(pipe);
@@ -1749,13 +1745,6 @@ static int link_pipe(struct pipe_inode_info *ipipe,
                i_tail++;
        } while (len);
 
-       /*
-        * return EAGAIN if we have the potential of some data in the
-        * future, otherwise just return 0
-        */
-       if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK))
-               ret = -EAGAIN;
-
        pipe_unlock(ipipe);
        pipe_unlock(opipe);
 
index eabc6ac..b79e3fd 100644 (file)
@@ -315,7 +315,7 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)
        if (arg.block_size != PAGE_SIZE)
                return -EINVAL;
 
-       if (arg.salt_size > FIELD_SIZEOF(struct fsverity_descriptor, salt))
+       if (arg.salt_size > sizeof_field(struct fsverity_descriptor, salt))
                return -EMSGSIZE;
 
        if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE)
index 4acc6e3..a9ad1f9 100644 (file)
@@ -5404,7 +5404,7 @@ __xfs_bunmapi(
                 * Make sure we don't touch multiple AGF headers out of order
                 * in a single transaction, as that could cause AB-BA deadlocks.
                 */
-               if (!wasdel) {
+               if (!wasdel && !isrt) {
                        agno = XFS_FSB_TO_AGNO(mp, del.br_startblock);
                        if (prev_agno != NULLAGNUMBER && prev_agno > agno)
                                break;
@@ -5480,16 +5480,17 @@ __xfs_bunmapi(
                }
                div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);
                if (mod) {
+                       xfs_extlen_t off = mp->m_sb.sb_rextsize - mod;
+
                        /*
                         * Realtime extent is lined up at the end but not
                         * at the front.  We'll get rid of full extents if
                         * we can.
                         */
-                       mod = mp->m_sb.sb_rextsize - mod;
-                       if (del.br_blockcount > mod) {
-                               del.br_blockcount -= mod;
-                               del.br_startoff += mod;
-                               del.br_startblock += mod;
+                       if (del.br_blockcount > off) {
+                               del.br_blockcount -= off;
+                               del.br_startoff += off;
+                               del.br_startblock += off;
                        } else if (del.br_startoff == start &&
                                   (del.br_state == XFS_EXT_UNWRITTEN ||
                                    tp->t_blk_res == 0)) {
@@ -5507,6 +5508,7 @@ __xfs_bunmapi(
                                continue;
                        } else if (del.br_state == XFS_EXT_UNWRITTEN) {
                                struct xfs_bmbt_irec    prev;
+                               xfs_fileoff_t           unwrite_start;
 
                                /*
                                 * This one is already unwritten.
@@ -5520,12 +5522,13 @@ __xfs_bunmapi(
                                ASSERT(!isnullstartblock(prev.br_startblock));
                                ASSERT(del.br_startblock ==
                                       prev.br_startblock + prev.br_blockcount);
-                               if (prev.br_startoff < start) {
-                                       mod = start - prev.br_startoff;
-                                       prev.br_blockcount -= mod;
-                                       prev.br_startblock += mod;
-                                       prev.br_startoff = start;
-                               }
+                               unwrite_start = max3(start,
+                                                    del.br_startoff - mod,
+                                                    prev.br_startoff);
+                               mod = unwrite_start - prev.br_startoff;
+                               prev.br_startoff = unwrite_start;
+                               prev.br_startblock += mod;
+                               prev.br_blockcount -= mod;
                                prev.br_state = XFS_EXT_UNWRITTEN;
                                error = xfs_bmap_add_extent_unwritten_real(tp,
                                                ip, whichfork, &icur, &cur,
index 6a147c6..f6006d9 100644 (file)
@@ -1542,6 +1542,8 @@ out_free_iclog:
                prev_iclog = iclog->ic_next;
                kmem_free(iclog->ic_data);
                kmem_free(iclog);
+               if (prev_iclog == log->l_iclog)
+                       break;
        }
 out_free_log:
        kmem_free(log);
diff --git a/include/asm-generic/4level-fixup.h b/include/asm-generic/4level-fixup.h
deleted file mode 100644 (file)
index c86cf7c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _4LEVEL_FIXUP_H
-#define _4LEVEL_FIXUP_H
-
-#define __ARCH_HAS_4LEVEL_HACK
-#define __PAGETABLE_PUD_FOLDED 1
-
-#define PUD_SHIFT                      PGDIR_SHIFT
-#define PUD_SIZE                       PGDIR_SIZE
-#define PUD_MASK                       PGDIR_MASK
-#define PTRS_PER_PUD                   1
-
-#define pud_t                          pgd_t
-
-#define pmd_alloc(mm, pud, address) \
-       ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
-               NULL: pmd_offset(pud, address))
-
-#define pud_offset(pgd, start)         (pgd)
-#define pud_none(pud)                  0
-#define pud_bad(pud)                   0
-#define pud_present(pud)               1
-#define pud_ERROR(pud)                 do { } while (0)
-#define pud_clear(pud)                 pgd_clear(pud)
-#define pud_val(pud)                   pgd_val(pud)
-#define pud_populate(mm, pud, pmd)     pgd_populate(mm, pud, pmd)
-#define pud_page(pud)                  pgd_page(pud)
-#define pud_page_vaddr(pud)            pgd_page_vaddr(pud)
-
-#undef pud_free_tlb
-#define pud_free_tlb(tlb, x, addr)     do { } while (0)
-#define pud_free(mm, x)                        do { } while (0)
-
-#undef  pud_addr_end
-#define pud_addr_end(addr, end)                (end)
-
-#include <asm-generic/5level-fixup.h>
-
-#endif
diff --git a/include/asm-generic/bitops-instrumented.h b/include/asm-generic/bitops-instrumented.h
deleted file mode 100644 (file)
index ddd1c6d..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/*
- * This file provides wrappers with sanitizer instrumentation for bit
- * operations.
- *
- * To use this functionality, an arch's bitops.h file needs to define each of
- * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
- * arch___set_bit(), etc.).
- */
-#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_H
-#define _ASM_GENERIC_BITOPS_INSTRUMENTED_H
-
-#include <linux/kasan-checks.h>
-
-/**
- * set_bit - Atomically set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * This is a relaxed atomic operation (no implied memory barriers).
- *
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- */
-static inline void set_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch_set_bit(nr, addr);
-}
-
-/**
- * __set_bit - Set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * Unlike set_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __set_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch___set_bit(nr, addr);
-}
-
-/**
- * clear_bit - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * This is a relaxed atomic operation (no implied memory barriers).
- */
-static inline void clear_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch_clear_bit(nr, addr);
-}
-
-/**
- * __clear_bit - Clears a bit in memory
- * @nr: the bit to clear
- * @addr: the address to start counting from
- *
- * Unlike clear_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __clear_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch___clear_bit(nr, addr);
-}
-
-/**
- * clear_bit_unlock - Clear a bit in memory, for unlock
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * This operation is atomic and provides release barrier semantics.
- */
-static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch_clear_bit_unlock(nr, addr);
-}
-
-/**
- * __clear_bit_unlock - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * This is a non-atomic operation but implies a release barrier before the
- * memory operation. It can be used for an unlock if no other CPUs can
- * concurrently modify other bits in the word.
- */
-static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch___clear_bit_unlock(nr, addr);
-}
-
-/**
- * change_bit - Toggle a bit in memory
- * @nr: Bit to change
- * @addr: Address to start counting from
- *
- * This is a relaxed atomic operation (no implied memory barriers).
- *
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- */
-static inline void change_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch_change_bit(nr, addr);
-}
-
-/**
- * __change_bit - Toggle a bit in memory
- * @nr: the bit to change
- * @addr: the address to start counting from
- *
- * Unlike change_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __change_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       arch___change_bit(nr, addr);
-}
-
-/**
- * test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This is an atomic fully-ordered operation (implied full memory barrier).
- */
-static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch_test_and_set_bit(nr, addr);
-}
-
-/**
- * __test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This operation is non-atomic. If two instances of this operation race, one
- * can appear to succeed but actually fail.
- */
-static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch___test_and_set_bit(nr, addr);
-}
-
-/**
- * test_and_set_bit_lock - Set a bit and return its old value, for lock
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This operation is atomic and provides acquire barrier semantics if
- * the returned value is 0.
- * It can be used to implement bit locks.
- */
-static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch_test_and_set_bit_lock(nr, addr);
-}
-
-/**
- * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This is an atomic fully-ordered operation (implied full memory barrier).
- */
-static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch_test_and_clear_bit(nr, addr);
-}
-
-/**
- * __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This operation is non-atomic. If two instances of this operation race, one
- * can appear to succeed but actually fail.
- */
-static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch___test_and_clear_bit(nr, addr);
-}
-
-/**
- * test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
- * @addr: Address to count from
- *
- * This is an atomic fully-ordered operation (implied full memory barrier).
- */
-static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch_test_and_change_bit(nr, addr);
-}
-
-/**
- * __test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
- * @addr: Address to count from
- *
- * This operation is non-atomic. If two instances of this operation race, one
- * can appear to succeed but actually fail.
- */
-static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch___test_and_change_bit(nr, addr);
-}
-
-/**
- * test_bit - Determine whether a bit is set
- * @nr: bit number to test
- * @addr: Address to start counting from
- */
-static inline bool test_bit(long nr, const volatile unsigned long *addr)
-{
-       kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
-       return arch_test_bit(nr, addr);
-}
-
-#if defined(arch_clear_bit_unlock_is_negative_byte)
-/**
- * clear_bit_unlock_is_negative_byte - Clear a bit in memory and test if bottom
- *                                     byte is negative, for unlock.
- * @nr: the bit to clear
- * @addr: the address to start counting from
- *
- * This operation is atomic and provides release barrier semantics.
- *
- * This is a bit of a one-trick-pony for the filemap code, which clears
- * PG_locked and tests PG_waiters,
- */
-static inline bool
-clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
-{
-       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
-       return arch_clear_bit_unlock_is_negative_byte(nr, addr);
-}
-/* Let everybody know we have it. */
-#define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
-#endif
-
-#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_H */
index 8a1ee10..9fdf213 100644 (file)
@@ -80,4 +80,21 @@ extern unsigned long find_first_zero_bit(const unsigned long *addr,
 
 #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
 
+/**
+ * find_next_clump8 - find next 8-bit clump with set bits in a memory region
+ * @clump: location to store copy of found clump
+ * @addr: address to base the search on
+ * @size: bitmap size in number of bits
+ * @offset: bit offset at which to start searching
+ *
+ * Returns the bit offset for the next set clump; the found clump value is
+ * copied to the location pointed by @clump. If no bits are set, returns @size.
+ */
+extern unsigned long find_next_clump8(unsigned long *clump,
+                                     const unsigned long *addr,
+                                     unsigned long size, unsigned long offset);
+
+#define find_first_clump8(clump, bits, size) \
+       find_next_clump8((clump), (bits), (size), 0)
+
 #endif /*_ASM_GENERIC_BITOPS_FIND_H_ */
diff --git a/include/asm-generic/bitops/instrumented-atomic.h b/include/asm-generic/bitops/instrumented-atomic.h
new file mode 100644 (file)
index 0000000..18ce3c9
--- /dev/null
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file provides wrappers with sanitizer instrumentation for atomic bit
+ * operations.
+ *
+ * To use this functionality, an arch's bitops.h file needs to define each of
+ * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
+ * arch___set_bit(), etc.).
+ */
+#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
+#define _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
+
+#include <linux/kasan-checks.h>
+
+/**
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This is a relaxed atomic operation (no implied memory barriers).
+ *
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void set_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch_set_bit(nr, addr);
+}
+
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * This is a relaxed atomic operation (no implied memory barriers).
+ */
+static inline void clear_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch_clear_bit(nr, addr);
+}
+
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ *
+ * This is a relaxed atomic operation (no implied memory barriers).
+ *
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void change_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch_change_bit(nr, addr);
+}
+
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This is an atomic fully-ordered operation (implied full memory barrier).
+ */
+static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch_test_and_set_bit(nr, addr);
+}
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This is an atomic fully-ordered operation (implied full memory barrier).
+ */
+static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch_test_and_clear_bit(nr, addr);
+}
+
+/**
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This is an atomic fully-ordered operation (implied full memory barrier).
+ */
+static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch_test_and_change_bit(nr, addr);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
diff --git a/include/asm-generic/bitops/instrumented-lock.h b/include/asm-generic/bitops/instrumented-lock.h
new file mode 100644 (file)
index 0000000..ec53fde
--- /dev/null
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file provides wrappers with sanitizer instrumentation for bit
+ * locking operations.
+ *
+ * To use this functionality, an arch's bitops.h file needs to define each of
+ * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
+ * arch___set_bit(), etc.).
+ */
+#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
+#define _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
+
+#include <linux/kasan-checks.h>
+
+/**
+ * clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is atomic and provides release barrier semantics.
+ */
+static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch_clear_bit_unlock(nr, addr);
+}
+
+/**
+ * __clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * This is a non-atomic operation but implies a release barrier before the
+ * memory operation. It can be used for an unlock if no other CPUs can
+ * concurrently modify other bits in the word.
+ */
+static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch___clear_bit_unlock(nr, addr);
+}
+
+/**
+ * test_and_set_bit_lock - Set a bit and return its old value, for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and provides acquire barrier semantics if
+ * the returned value is 0.
+ * It can be used to implement bit locks.
+ */
+static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch_test_and_set_bit_lock(nr, addr);
+}
+
+#if defined(arch_clear_bit_unlock_is_negative_byte)
+/**
+ * clear_bit_unlock_is_negative_byte - Clear a bit in memory and test if bottom
+ *                                     byte is negative, for unlock.
+ * @nr: the bit to clear
+ * @addr: the address to start counting from
+ *
+ * This operation is atomic and provides release barrier semantics.
+ *
+ * This is a bit of a one-trick-pony for the filemap code, which clears
+ * PG_locked and tests PG_waiters,
+ */
+static inline bool
+clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch_clear_bit_unlock_is_negative_byte(nr, addr);
+}
+/* Let everybody know we have it. */
+#define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
+#endif
+
+#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H */
diff --git a/include/asm-generic/bitops/instrumented-non-atomic.h b/include/asm-generic/bitops/instrumented-non-atomic.h
new file mode 100644 (file)
index 0000000..95ff28d
--- /dev/null
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file provides wrappers with sanitizer instrumentation for non-atomic
+ * bit operations.
+ *
+ * To use this functionality, an arch's bitops.h file needs to define each of
+ * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
+ * arch___set_bit(), etc.).
+ */
+#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
+#define _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
+
+#include <linux/kasan-checks.h>
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __set_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch___set_bit(nr, addr);
+}
+
+/**
+ * __clear_bit - Clears a bit in memory
+ * @nr: the bit to clear
+ * @addr: the address to start counting from
+ *
+ * Unlike clear_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __clear_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch___clear_bit(nr, addr);
+}
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __change_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       arch___change_bit(nr, addr);
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic. If two instances of this operation race, one
+ * can appear to succeed but actually fail.
+ */
+static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch___test_and_set_bit(nr, addr);
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic. If two instances of this operation race, one
+ * can appear to succeed but actually fail.
+ */
+static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch___test_and_clear_bit(nr, addr);
+}
+
+/**
+ * __test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic. If two instances of this operation race, one
+ * can appear to succeed but actually fail.
+ */
+static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
+{
+       kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+       return arch___test_and_change_bit(nr, addr);
+}
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline bool test_bit(long nr, const volatile unsigned long *addr)
+{
+       kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
+       return arch_test_bit(nr, addr);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
index dc5c1c7..6d6bac1 100644 (file)
@@ -50,9 +50,9 @@
 #define RK_PD7         31
 
 #define RK_FUNC_GPIO   0
-#define RK_FUNC_1      1
-#define RK_FUNC_2      2
-#define RK_FUNC_3      3
-#define RK_FUNC_4      4
+#define RK_FUNC_1      1 /* deprecated */
+#define RK_FUNC_2      2 /* deprecated */
+#define RK_FUNC_3      3 /* deprecated */
+#define RK_FUNC_4      4 /* deprecated */
 
 #endif
index 93e36d0..f05f8b1 100644 (file)
 #define RPMH_REGULATOR_LEVEL_TURBO     384
 #define RPMH_REGULATOR_LEVEL_TURBO_L1  416
 
+/* MSM8976 Power Domain Indexes */
+#define MSM8976_VDDCX          0
+#define MSM8976_VDDCX_AO       1
+#define MSM8976_VDDCX_VFL      2
+#define MSM8976_VDDMX          3
+#define MSM8976_VDDMX_AO       4
+#define MSM8976_VDDMX_VFL      5
+
 /* MSM8996 Power Domain Indexes */
 #define MSM8996_VDDCX          0
 #define MSM8996_VDDCX_AO       1
@@ -68,6 +76,7 @@
 #define RPM_SMD_LEVEL_NOM_PLUS        320
 #define RPM_SMD_LEVEL_TURBO           384
 #define RPM_SMD_LEVEL_TURBO_NO_CPR    416
+#define RPM_SMD_LEVEL_TURBO_HIGH      448
 #define RPM_SMD_LEVEL_BINNING         512
 
 #endif
diff --git a/include/dt-bindings/reset/amlogic,meson-a1-reset.h b/include/dt-bindings/reset/amlogic,meson-a1-reset.h
new file mode 100644 (file)
index 0000000..f1a3a79
--- /dev/null
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Xingyu Chen <xingyu.chen@amlogic.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_A1_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_A1_RESET_H
+
+/*     RESET0                                  */
+/*                                     0       */
+#define RESET_AM2AXI_VAD               1
+/*                                     2-3     */
+#define RESET_PSRAM                    4
+#define RESET_PAD_CTRL                 5
+/*                                     6       */
+#define RESET_TEMP_SENSOR              7
+#define RESET_AM2AXI_DEV               8
+/*                                     9       */
+#define RESET_SPICC_A                  10
+#define RESET_MSR_CLK                  11
+#define RESET_AUDIO                    12
+#define RESET_ANALOG_CTRL              13
+#define RESET_SAR_ADC                  14
+#define RESET_AUDIO_VAD                        15
+#define RESET_CEC                      16
+#define RESET_PWM_EF                   17
+#define RESET_PWM_CD                   18
+#define RESET_PWM_AB                   19
+/*                                     20      */
+#define RESET_IR_CTRL                  21
+#define RESET_I2C_S_A                  22
+/*                                     23      */
+#define RESET_I2C_M_D                  24
+#define RESET_I2C_M_C                  25
+#define RESET_I2C_M_B                  26
+#define RESET_I2C_M_A                  27
+#define RESET_I2C_PROD_AHB             28
+#define RESET_I2C_PROD                 29
+/*                                     30-31   */
+
+/*     RESET1                                  */
+#define RESET_ACODEC                   32
+#define RESET_DMA                      33
+#define RESET_SD_EMMC_A                        34
+/*                                     35      */
+#define RESET_USBCTRL                  36
+/*                                     37      */
+#define RESET_USBPHY                   38
+/*                                     39-41   */
+#define RESET_RSA                      42
+#define RESET_DMC                      43
+/*                                     44      */
+#define RESET_IRQ_CTRL                 45
+/*                                     46      */
+#define RESET_NIC_VAD                  47
+#define RESET_NIC_AXI                  48
+#define RESET_RAMA                     49
+#define RESET_RAMB                     50
+/*                                     51-52   */
+#define RESET_ROM                      53
+#define RESET_SPIFC                    54
+#define RESET_GIC                      55
+#define RESET_UART_C                   56
+#define RESET_UART_B                   57
+#define RESET_UART_A                   58
+#define RESET_OSC_RING                 59
+/*                                     60-63   */
+
+/*     RESET2                                  */
+/*                                     64-95   */
+
+#endif
index 05c3636..1ef8078 100644 (file)
@@ -13,5 +13,7 @@
 #define AXG_ARB_FRDDR_A        3
 #define AXG_ARB_FRDDR_B        4
 #define AXG_ARB_FRDDR_C        5
+#define AXG_ARB_TODDR_D        6
+#define AXG_ARB_FRDDR_D        7
 
 #endif /* _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H */
diff --git a/include/dt-bindings/reset/realtek,rtd1295.h b/include/dt-bindings/reset/realtek,rtd1295.h
new file mode 100644 (file)
index 0000000..2c0cb6a
--- /dev/null
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
+/*
+ * Realtek RTD1295 reset controllers
+ *
+ * Copyright (c) 2017 Andreas Färber
+ */
+#ifndef DT_BINDINGS_RESET_RTD1295_H
+#define DT_BINDINGS_RESET_RTD1295_H
+
+/* soft reset 1 */
+#define RTD1295_RSTN_MISC              0
+#define RTD1295_RSTN_NAT               1
+#define RTD1295_RSTN_USB3_PHY0_POW     2
+#define RTD1295_RSTN_GSPI              3
+#define RTD1295_RSTN_USB3_P0_MDIO      4
+#define RTD1295_RSTN_SATA_0            5
+#define RTD1295_RSTN_USB               6
+#define RTD1295_RSTN_SATA_PHY_0                7
+#define RTD1295_RSTN_USB_PHY0          8
+#define RTD1295_RSTN_USB_PHY1          9
+#define RTD1295_RSTN_SATA_PHY_POW_0    10
+#define RTD1295_RSTN_SATA_FUNC_EXIST_0 11
+#define RTD1295_RSTN_HDMI              12
+#define RTD1295_RSTN_VE1               13
+#define RTD1295_RSTN_VE2               14
+#define RTD1295_RSTN_VE3               15
+#define RTD1295_RSTN_ETN               16
+#define RTD1295_RSTN_AIO               17
+#define RTD1295_RSTN_GPU               18
+#define RTD1295_RSTN_TVE               19
+#define RTD1295_RSTN_VO                        20
+#define RTD1295_RSTN_LVDS              21
+#define RTD1295_RSTN_SE                        22
+#define RTD1295_RSTN_DCU               23
+#define RTD1295_RSTN_DC_PHY            24
+#define RTD1295_RSTN_CP                        25
+#define RTD1295_RSTN_MD                        26
+#define RTD1295_RSTN_TP                        27
+#define RTD1295_RSTN_AE                        28
+#define RTD1295_RSTN_NF                        29
+#define RTD1295_RSTN_MIPI              30
+#define RTD1295_RSTN_RSA               31
+
+/* soft reset 2 */
+#define RTD1295_RSTN_ACPU              0
+#define RTD1295_RSTN_JPEG              1
+#define RTD1295_RSTN_USB_PHY3          2
+#define RTD1295_RSTN_USB_PHY2          3
+#define RTD1295_RSTN_USB3_PHY1_POW     4
+#define RTD1295_RSTN_USB3_P1_MDIO      5
+#define RTD1295_RSTN_PCIE0_STITCH      6
+#define RTD1295_RSTN_PCIE0_PHY         7
+#define RTD1295_RSTN_PCIE0             8
+#define RTD1295_RSTN_PCR_CNT           9
+#define RTD1295_RSTN_CR                        10
+#define RTD1295_RSTN_EMMC              11
+#define RTD1295_RSTN_SDIO              12
+#define RTD1295_RSTN_PCIE0_CORE                13
+#define RTD1295_RSTN_PCIE0_POWER       14
+#define RTD1295_RSTN_PCIE0_NONSTICH    15
+#define RTD1295_RSTN_PCIE1_PHY         16
+#define RTD1295_RSTN_PCIE1             17
+#define RTD1295_RSTN_I2C_5             18
+#define RTD1295_RSTN_PCIE1_STITCH      19
+#define RTD1295_RSTN_PCIE1_CORE                20
+#define RTD1295_RSTN_PCIE1_POWER       21
+#define RTD1295_RSTN_PCIE1_NONSTICH    22
+#define RTD1295_RSTN_I2C_4             23
+#define RTD1295_RSTN_I2C_3             24
+#define RTD1295_RSTN_I2C_2             25
+#define RTD1295_RSTN_I2C_1             26
+#define RTD1295_RSTN_UR2               27
+#define RTD1295_RSTN_UR1               28
+#define RTD1295_RSTN_MISC_SC           29
+#define RTD1295_RSTN_CBUS_TX           30
+#define RTD1295_RSTN_SDS_PHY           31
+
+/* soft reset 4 */
+#define RTD1295_RSTN_DCPHY_CRT         0
+#define RTD1295_RSTN_DCPHY_ALERT_RX    1
+#define RTD1295_RSTN_DCPHY_PTR         2
+#define RTD1295_RSTN_DCPHY_LDO         3
+#define RTD1295_RSTN_DCPHY_SSC_DIG     4
+#define RTD1295_RSTN_HDMIRX            5
+#define RTD1295_RSTN_CBUSRX            6
+#define RTD1295_RSTN_SATA_PHY_POW_1    7
+#define RTD1295_RSTN_SATA_FUNC_EXIST_1 8
+#define RTD1295_RSTN_SATA_PHY_1                9
+#define RTD1295_RSTN_SATA_1            10
+#define RTD1295_RSTN_FAN               11
+#define RTD1295_RSTN_HDMIRX_WRAP       12
+#define RTD1295_RSTN_PCIE0_PHY_MDIO    13
+#define RTD1295_RSTN_PCIE1_PHY_MDIO    14
+#define RTD1295_RSTN_DISP              15
+
+/* iso reset */
+#define RTD1295_ISO_RSTN_IR            1
+#define RTD1295_ISO_RSTN_CEC0          2
+#define RTD1295_ISO_RSTN_CEC1          3
+#define RTD1295_ISO_RSTN_DP            4
+#define RTD1295_ISO_RSTN_CBUSTX                5
+#define RTD1295_ISO_RSTN_CBUSRX                6
+#define RTD1295_ISO_RSTN_EFUSE         7
+#define RTD1295_ISO_RSTN_UR0           8
+#define RTD1295_ISO_RSTN_GMAC          9
+#define RTD1295_ISO_RSTN_GPHY          10
+#define RTD1295_ISO_RSTN_I2C_0         11
+#define RTD1295_ISO_RSTN_I2C_1         12
+#define RTD1295_ISO_RSTN_CBUS          13
+
+#endif
index c6b61ca..21b34a9 100644 (file)
@@ -30,8 +30,6 @@
 #include <linux/agp_backend.h>
 #include <uapi/linux/agpgart.h>
 
-#define AGPGART_MINOR 175
-
 struct agp_info {
        struct agp_version version;     /* version of the driver        */
        u32 bridge_id;          /* bridge vendor/device         */
index 29fc933..ff335b2 100644 (file)
@@ -53,6 +53,7 @@
  *  bitmap_find_next_zero_area_off(buf, len, pos, n, mask)  as above
  *  bitmap_shift_right(dst, src, n, nbits)      *dst = *src >> n
  *  bitmap_shift_left(dst, src, n, nbits)       *dst = *src << n
+ *  bitmap_replace(dst, old, new, mask, nbits)  *dst = (*old & ~(*mask)) | (*new & *mask)
  *  bitmap_remap(dst, src, old, new, nbits)     *dst = map(old, new)(src)
  *  bitmap_bitremap(oldbit, old, new, nbits)    newbit = map(old, new)(oldbit)
  *  bitmap_onto(dst, orig, relmap, nbits)       *dst = orig relative to relmap
@@ -66,6 +67,8 @@
  *  bitmap_allocate_region(bitmap, pos, order)  Allocate specified bit region
  *  bitmap_from_arr32(dst, buf, nbits)          Copy nbits from u32[] buf to dst
  *  bitmap_to_arr32(buf, src, nbits)            Copy nbits from buf to u32[] dst
+ *  bitmap_get_value8(map, start)               Get 8bit value from map at start
+ *  bitmap_set_value8(map, value, start)        Set 8bit value to map at start
  *
  * Note, bitmap_zero() and bitmap_fill() operate over the region of
  * unsigned longs, that is, bits behind bitmap till the unsigned long
@@ -138,6 +141,9 @@ extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
                        const unsigned long *bitmap2, unsigned int nbits);
 extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
                        const unsigned long *bitmap2, unsigned int nbits);
+extern void __bitmap_replace(unsigned long *dst,
+                       const unsigned long *old, const unsigned long *new,
+                       const unsigned long *mask, unsigned int nbits);
 extern int __bitmap_intersects(const unsigned long *bitmap1,
                        const unsigned long *bitmap2, unsigned int nbits);
 extern int __bitmap_subset(const unsigned long *bitmap1,
@@ -432,6 +438,18 @@ static inline void bitmap_shift_left(unsigned long *dst, const unsigned long *sr
                __bitmap_shift_left(dst, src, shift, nbits);
 }
 
+static inline void bitmap_replace(unsigned long *dst,
+                                 const unsigned long *old,
+                                 const unsigned long *new,
+                                 const unsigned long *mask,
+                                 unsigned int nbits)
+{
+       if (small_const_nbits(nbits))
+               *dst = (*old & ~(*mask)) | (*new & *mask);
+       else
+               __bitmap_replace(dst, old, new, mask, nbits);
+}
+
 static inline int bitmap_parse(const char *buf, unsigned int buflen,
                        unsigned long *maskp, int nmaskbits)
 {
@@ -489,6 +507,39 @@ static inline void bitmap_from_u64(unsigned long *dst, u64 mask)
                dst[1] = mask >> 32;
 }
 
+/**
+ * bitmap_get_value8 - get an 8-bit value within a memory region
+ * @map: address to the bitmap memory region
+ * @start: bit offset of the 8-bit value; must be a multiple of 8
+ *
+ * Returns the 8-bit value located at the @start bit offset within the @src
+ * memory region.
+ */
+static inline unsigned long bitmap_get_value8(const unsigned long *map,
+                                             unsigned long start)
+{
+       const size_t index = BIT_WORD(start);
+       const unsigned long offset = start % BITS_PER_LONG;
+
+       return (map[index] >> offset) & 0xFF;
+}
+
+/**
+ * bitmap_set_value8 - set an 8-bit value within a memory region
+ * @map: address to the bitmap memory region
+ * @value: the 8-bit value; values wider than 8 bits may clobber bitmap
+ * @start: bit offset of the 8-bit value; must be a multiple of 8
+ */
+static inline void bitmap_set_value8(unsigned long *map, unsigned long value,
+                                    unsigned long start)
+{
+       const size_t index = BIT_WORD(start);
+       const unsigned long offset = start % BITS_PER_LONG;
+
+       map[index] &= ~(0xFFUL << offset);
+       map[index] |= value << offset;
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __LINUX_BITMAP_H */
index c94a9ff..e479067 100644 (file)
@@ -47,6 +47,18 @@ extern unsigned long __sw_hweight64(__u64 w);
             (bit) < (size);                                    \
             (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
 
+/**
+ * for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
+ * @start: bit offset to start search and to store the current iteration offset
+ * @clump: location to store copy of current 8-bit clump
+ * @bits: bitmap address to base the search on
+ * @size: bitmap size in number of bits
+ */
+#define for_each_set_clump8(start, clump, bits, size) \
+       for ((start) = find_first_clump8(&(clump), (bits), (size)); \
+            (start) < (size); \
+            (start) = find_next_clump8(&(clump), (bits), (size), (start) + 8))
+
 static inline int get_bitmask_order(unsigned int count)
 {
        int order;
index 19394c7..e4a6949 100644 (file)
@@ -188,7 +188,6 @@ struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
 struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
                                    struct request_queue *q);
 int blkcg_init_queue(struct request_queue *q);
-void blkcg_drain_queue(struct request_queue *q);
 void blkcg_exit_queue(struct request_queue *q);
 
 /* Blkio controller policy registration */
@@ -720,7 +719,6 @@ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { ret
 static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
 { return NULL; }
 static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
-static inline void blkcg_drain_queue(struct request_queue *q) { }
 static inline void blkcg_exit_queue(struct request_queue *q) { }
 static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
 static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
index 6012e25..47eb22a 100644 (file)
@@ -357,8 +357,7 @@ typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx,
 #define BLK_ALL_ZONES  ((unsigned int)-1)
 int blkdev_report_zones(struct block_device *bdev, sector_t sector,
                        unsigned int nr_zones, report_zones_cb cb, void *data);
-
-extern unsigned int blkdev_nr_zones(struct block_device *bdev);
+unsigned int blkdev_nr_zones(struct gendisk *disk);
 extern int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op,
                            sector_t sectors, sector_t nr_sectors,
                            gfp_t gfp_mask);
@@ -371,12 +370,7 @@ extern int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode,
 
 #else /* CONFIG_BLK_DEV_ZONED */
 
-static inline unsigned int blkdev_nr_zones(struct block_device *bdev)
-{
-       return 0;
-}
-
-static inline int blk_revalidate_disk_zones(struct gendisk *disk)
+static inline unsigned int blkdev_nr_zones(struct gendisk *disk)
 {
        return 0;
 }
@@ -504,9 +498,9 @@ struct request_queue {
        /*
         * Zoned block device information for request dispatch control.
         * nr_zones is the total number of zones of the device. This is always
-        * 0 for regular block devices. seq_zones_bitmap is a bitmap of nr_zones
-        * bits which indicates if a zone is conventional (bit clear) or
-        * sequential (bit set). seq_zones_wlock is a bitmap of nr_zones
+        * 0 for regular block devices. conv_zones_bitmap is a bitmap of nr_zones
+        * bits which indicates if a zone is conventional (bit set) or
+        * sequential (bit clear). seq_zones_wlock is a bitmap of nr_zones
         * bits which indicates if a zone is write locked, that is, if a write
         * request targeting the zone was dispatched. All three fields are
         * initialized by the low level device driver (e.g. scsi/sd.c).
@@ -519,7 +513,7 @@ struct request_queue {
         * blk_mq_unfreeze_queue().
         */
        unsigned int            nr_zones;
-       unsigned long           *seq_zones_bitmap;
+       unsigned long           *conv_zones_bitmap;
        unsigned long           *seq_zones_wlock;
 #endif /* CONFIG_BLK_DEV_ZONED */
 
@@ -724,9 +718,11 @@ static inline unsigned int blk_queue_zone_no(struct request_queue *q,
 static inline bool blk_queue_zone_is_seq(struct request_queue *q,
                                         sector_t sector)
 {
-       if (!blk_queue_is_zoned(q) || !q->seq_zones_bitmap)
+       if (!blk_queue_is_zoned(q))
                return false;
-       return test_bit(blk_queue_zone_no(q, sector), q->seq_zones_bitmap);
+       if (!q->conv_zones_bitmap)
+               return true;
+       return !test_bit(blk_queue_zone_no(q, sector), q->conv_zones_bitmap);
 }
 #else /* CONFIG_BLK_DEV_ZONED */
 static inline unsigned int blk_queue_nr_zones(struct request_queue *q)
index 0fe5426..e3a0be2 100644 (file)
@@ -9,11 +9,11 @@
 #else /* __CHECKER__ */
 /*
  * Force a compilation error if condition is true, but also produce a
- * result (of value 0 and type size_t), so the expression can be used
+ * result (of value 0 and type int), so the expression can be used
  * e.g. in a structure initializer (or where-ever else comma expressions
  * aren't permitted).
  */
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
+#define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
 #endif /* __CHECKER__ */
 
 /* Force a compilation error if a constant expression is not a power of 2 */
index a032f01..679a422 100644 (file)
@@ -87,26 +87,24 @@ struct bvec_iter_all {
 static inline bool bvec_iter_advance(const struct bio_vec *bv,
                struct bvec_iter *iter, unsigned bytes)
 {
+       unsigned int idx = iter->bi_idx;
+
        if (WARN_ONCE(bytes > iter->bi_size,
                     "Attempted to advance past end of bvec iter\n")) {
                iter->bi_size = 0;
                return false;
        }
 
-       while (bytes) {
-               const struct bio_vec *cur = bv + iter->bi_idx;
-               unsigned len = min3(bytes, iter->bi_size,
-                                   cur->bv_len - iter->bi_bvec_done);
-
-               bytes -= len;
-               iter->bi_size -= len;
-               iter->bi_bvec_done += len;
+       iter->bi_size -= bytes;
+       bytes += iter->bi_bvec_done;
 
-               if (iter->bi_bvec_done == cur->bv_len) {
-                       iter->bi_bvec_done = 0;
-                       iter->bi_idx++;
-               }
+       while (bytes && bytes >= bv[idx].bv_len) {
+               bytes -= bv[idx].bv_len;
+               idx++;
        }
+
+       iter->bi_idx = idx;
+       iter->bi_bvec_done = bytes;
        return true;
 }
 
index b9dbda1..8fe9b80 100644 (file)
@@ -280,10 +280,12 @@ extern const char *ceph_msg_type_name(int type);
 extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
 extern void *ceph_kvmalloc(size_t size, gfp_t flags);
 
-extern struct ceph_options *ceph_parse_options(char *options,
-                             const char *dev_name, const char *dev_name_end,
-                             int (*parse_extra_token)(char *c, void *private),
-                             void *private);
+struct fs_parameter;
+struct ceph_options *ceph_alloc_options(void);
+int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
+                      struct fs_context *fc);
+int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
+                    struct fs_context *fc);
 int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
                              bool show_all);
 extern void ceph_destroy_options(struct ceph_options *opt);
index bae54bb..b747325 100644 (file)
@@ -33,6 +33,13 @@ cpufreq_cooling_register(struct cpufreq_policy *policy);
  */
 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev);
 
+/**
+ * of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
+ * @policy: cpufreq policy.
+ */
+struct thermal_cooling_device *
+of_cpufreq_cooling_register(struct cpufreq_policy *policy);
+
 #else /* !CONFIG_CPU_THERMAL */
 static inline struct thermal_cooling_device *
 cpufreq_cooling_register(struct cpufreq_policy *policy)
@@ -45,21 +52,12 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 {
        return;
 }
-#endif /* CONFIG_CPU_THERMAL */
 
-#if defined(CONFIG_THERMAL_OF) && defined(CONFIG_CPU_THERMAL)
-/**
- * of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
- * @policy: cpufreq policy.
- */
-struct thermal_cooling_device *
-of_cpufreq_cooling_register(struct cpufreq_policy *policy);
-#else
 static inline struct thermal_cooling_device *
 of_cpufreq_cooling_register(struct cpufreq_policy *policy)
 {
        return NULL;
 }
-#endif /* defined(CONFIG_THERMAL_OF) && defined(CONFIG_CPU_THERMAL) */
+#endif /* CONFIG_CPU_THERMAL */
 
 #endif /* __CPU_COOLING_H__ */
index 2dbe46b..1dabe36 100644 (file)
@@ -54,7 +54,6 @@ struct cpuidle_state {
        unsigned int    exit_latency; /* in US */
        int             power_usage; /* in mW */
        unsigned int    target_residency; /* in US */
-       bool            disabled; /* disabled on all CPUs */
 
        int (*enter)    (struct cpuidle_device *dev,
                        struct cpuidle_driver *drv,
@@ -77,6 +76,7 @@ struct cpuidle_state {
 #define CPUIDLE_FLAG_POLLING   BIT(0) /* polling state */
 #define CPUIDLE_FLAG_COUPLED   BIT(1) /* state applies to multiple cpus */
 #define CPUIDLE_FLAG_TIMER_STOP BIT(2) /* timer is stopped on this state */
+#define CPUIDLE_FLAG_UNUSABLE  BIT(3) /* avoid using this state */
 
 struct cpuidle_device_kobj;
 struct cpuidle_state_kobj;
index 10090f1..c1488cc 100644 (file)
@@ -440,6 +440,11 @@ static inline bool d_is_negative(const struct dentry *dentry)
        return d_is_miss(dentry);
 }
 
+static inline bool d_flags_negative(unsigned flags)
+{
+       return (flags & DCACHE_ENTRY_TYPE) == DCACHE_MISS_TYPE;
+}
+
 static inline bool d_is_positive(const struct dentry *dentry)
 {
        return !d_is_negative(dentry);
index 2bae9ed..fb376b5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/pm_opp.h>
+#include <linux/pm_qos.h>
 
 #define DEVFREQ_NAME_LEN 16
 
@@ -123,8 +124,8 @@ struct devfreq_dev_profile {
  * @previous_freq:     previously configured frequency value.
  * @data:      Private data of the governor. The devfreq framework does not
  *             touch this.
- * @min_freq:  Limit minimum frequency requested by user (0: none)
- * @max_freq:  Limit maximum frequency requested by user (0: none)
+ * @user_min_freq_req: PM QoS minimum frequency request from user (via sysfs)
+ * @user_max_freq_req: PM QoS maximum frequency request from user (via sysfs)
  * @scaling_min_freq:  Limit minimum frequency requested by OPP interface
  * @scaling_max_freq:  Limit maximum frequency requested by OPP interface
  * @stop_polling:       devfreq polling status of a device.
@@ -136,6 +137,8 @@ struct devfreq_dev_profile {
  * @time_in_state:     Statistics of devfreq states
  * @last_stat_updated: The last time stat updated
  * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier
+ * @nb_min:            Notifier block for DEV_PM_QOS_MIN_FREQUENCY
+ * @nb_max:            Notifier block for DEV_PM_QOS_MAX_FREQUENCY
  *
  * This structure stores the devfreq information for a give device.
  *
@@ -161,8 +164,8 @@ struct devfreq {
 
        void *data; /* private data for governors */
 
-       unsigned long min_freq;
-       unsigned long max_freq;
+       struct dev_pm_qos_request user_min_freq_req;
+       struct dev_pm_qos_request user_max_freq_req;
        unsigned long scaling_min_freq;
        unsigned long scaling_max_freq;
        bool stop_polling;
@@ -178,6 +181,9 @@ struct devfreq {
        unsigned long last_stat_updated;
 
        struct srcu_notifier_head transition_notifier_list;
+
+       struct notifier_block nb_min;
+       struct notifier_block nb_max;
 };
 
 struct devfreq_freqs {
index e226030..96ff767 100644 (file)
@@ -1666,11 +1666,11 @@ extern bool kill_device(struct device *dev);
 #ifdef CONFIG_DEVTMPFS
 extern int devtmpfs_create_node(struct device *dev);
 extern int devtmpfs_delete_node(struct device *dev);
-extern int devtmpfs_mount(const char *mntdir);
+extern int devtmpfs_mount(void);
 #else
 static inline int devtmpfs_create_node(struct device *dev) { return 0; }
 static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
-static inline int devtmpfs_mount(const char *mountpoint) { return 0; }
+static inline int devtmpfs_mount(void) { return 0; }
 #endif
 
 /* drivers/base/power/shutdown.c */
index 73f8c3c..d249b88 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/sched/topology.h>
 #include <linux/types.h>
 
-#ifdef CONFIG_ENERGY_MODEL
 /**
  * em_cap_state - Capacity state of a performance domain
  * @frequency: The CPU frequency in KHz, for consistency with CPUFreq
@@ -40,6 +39,7 @@ struct em_perf_domain {
        unsigned long cpus[0];
 };
 
+#ifdef CONFIG_ENERGY_MODEL
 #define EM_CPU_MAX_POWER 0xFFFF
 
 struct em_data_callback {
@@ -160,7 +160,6 @@ static inline int em_pd_nr_cap_states(struct em_perf_domain *pd)
 }
 
 #else
-struct em_perf_domain {};
 struct em_data_callback {};
 #define EM_DATA_CB(_active_power_cb) { }
 
index aee5c86..6278414 100644 (file)
@@ -47,7 +47,7 @@ extern struct module __this_module;
  * absolute relocations that require runtime processing on relocatable
  * kernels.
  */
-#define __KSYMTAB_ENTRY_NS(sym, sec)                                   \
+#define __KSYMTAB_ENTRY(sym, sec)                                      \
        __ADDRESSABLE(sym)                                              \
        asm("   .section \"___ksymtab" sec "+" #sym "\", \"a\"  \n"     \
            "   .balign 4                                       \n"     \
@@ -57,33 +57,17 @@ extern struct module __this_module;
            "   .long   __kstrtabns_" #sym "- .                 \n"     \
            "   .previous                                       \n")
 
-#define __KSYMTAB_ENTRY(sym, sec)                                      \
-       __ADDRESSABLE(sym)                                              \
-       asm("   .section \"___ksymtab" sec "+" #sym "\", \"a\"  \n"     \
-           "   .balign 4                                       \n"     \
-           "__ksymtab_" #sym ":                                \n"     \
-           "   .long   " #sym "- .                             \n"     \
-           "   .long   __kstrtab_" #sym "- .                   \n"     \
-           "   .long   0                                       \n"     \
-           "   .previous                                       \n")
-
 struct kernel_symbol {
        int value_offset;
        int name_offset;
        int namespace_offset;
 };
 #else
-#define __KSYMTAB_ENTRY_NS(sym, sec)                                   \
-       static const struct kernel_symbol __ksymtab_##sym               \
-       __attribute__((section("___ksymtab" sec "+" #sym), used))       \
-       __aligned(sizeof(void *))                                       \
-       = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym }
-
 #define __KSYMTAB_ENTRY(sym, sec)                                      \
        static const struct kernel_symbol __ksymtab_##sym               \
        __attribute__((section("___ksymtab" sec "+" #sym), used))       \
        __aligned(sizeof(void *))                                       \
-       = { (unsigned long)&sym, __kstrtab_##sym, NULL }
+       = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym }
 
 struct kernel_symbol {
        unsigned long value;
@@ -94,28 +78,20 @@ struct kernel_symbol {
 
 #ifdef __GENKSYMS__
 
-#define ___EXPORT_SYMBOL(sym,sec)      __GENKSYMS_EXPORT_SYMBOL(sym)
-#define ___EXPORT_SYMBOL_NS(sym,sec,ns)        __GENKSYMS_EXPORT_SYMBOL(sym)
+#define ___EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
 
 #else
 
-#define ___export_symbol_common(sym, sec)                              \
+/* For every exported symbol, place a struct in the __ksymtab section */
+#define ___EXPORT_SYMBOL(sym, sec, ns)                                 \
        extern typeof(sym) sym;                                         \
        __CRC_SYMBOL(sym, sec);                                         \
        static const char __kstrtab_##sym[]                             \
        __attribute__((section("__ksymtab_strings"), used, aligned(1))) \
-       = #sym                                                          \
-
-/* For every exported symbol, place a struct in the __ksymtab section */
-#define ___EXPORT_SYMBOL_NS(sym, sec, ns)                              \
-       ___export_symbol_common(sym, sec);                              \
+       = #sym;                                                         \
        static const char __kstrtabns_##sym[]                           \
        __attribute__((section("__ksymtab_strings"), used, aligned(1))) \
-       = #ns;                                                          \
-       __KSYMTAB_ENTRY_NS(sym, sec)
-
-#define ___EXPORT_SYMBOL(sym, sec)                                     \
-       ___export_symbol_common(sym, sec);                              \
+       = ns;                                                           \
        __KSYMTAB_ENTRY(sym, sec)
 
 #endif
@@ -127,8 +103,7 @@ struct kernel_symbol {
  * be reused in other execution contexts such as the UEFI stub or the
  * decompressor.
  */
-#define __EXPORT_SYMBOL_NS(sym, sec, ns)
-#define __EXPORT_SYMBOL(sym, sec)
+#define __EXPORT_SYMBOL(sym, sec, ns)
 
 #elif defined(CONFIG_TRIM_UNUSED_KSYMS)
 
@@ -144,48 +119,38 @@ struct kernel_symbol {
 #define __ksym_marker(sym)     \
        static int __ksym_marker_##sym[0] __section(".discard.ksym") __used
 
-#define __EXPORT_SYMBOL(sym, sec)                              \
-       __ksym_marker(sym);                                     \
-       __cond_export_sym(sym, sec, __is_defined(__KSYM_##sym))
-#define __cond_export_sym(sym, sec, conf)                      \
-       ___cond_export_sym(sym, sec, conf)
-#define ___cond_export_sym(sym, sec, enabled)                  \
-       __cond_export_sym_##enabled(sym, sec)
-#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
-#define __cond_export_sym_0(sym, sec) /* nothing */
-
-#define __EXPORT_SYMBOL_NS(sym, sec, ns)                               \
+#define __EXPORT_SYMBOL(sym, sec, ns)                                  \
        __ksym_marker(sym);                                             \
-       __cond_export_ns_sym(sym, sec, ns, __is_defined(__KSYM_##sym))
-#define __cond_export_ns_sym(sym, sec, ns, conf)                       \
-       ___cond_export_ns_sym(sym, sec, ns, conf)
-#define ___cond_export_ns_sym(sym, sec, ns, enabled)                   \
-       __cond_export_ns_sym_##enabled(sym, sec, ns)
-#define __cond_export_ns_sym_1(sym, sec, ns) ___EXPORT_SYMBOL_NS(sym, sec, ns)
-#define __cond_export_ns_sym_0(sym, sec, ns) /* nothing */
+       __cond_export_sym(sym, sec, ns, __is_defined(__KSYM_##sym))
+#define __cond_export_sym(sym, sec, ns, conf)                          \
+       ___cond_export_sym(sym, sec, ns, conf)
+#define ___cond_export_sym(sym, sec, ns, enabled)                      \
+       __cond_export_sym_##enabled(sym, sec, ns)
+#define __cond_export_sym_1(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
+#define __cond_export_sym_0(sym, sec, ns) /* nothing */
 
 #else
 
-#define __EXPORT_SYMBOL_NS(sym,sec,ns) ___EXPORT_SYMBOL_NS(sym,sec,ns)
-#define __EXPORT_SYMBOL(sym,sec)       ___EXPORT_SYMBOL(sym,sec)
+#define __EXPORT_SYMBOL(sym, sec, ns)  ___EXPORT_SYMBOL(sym, sec, ns)
 
 #endif /* CONFIG_MODULES */
 
 #ifdef DEFAULT_SYMBOL_NAMESPACE
-#undef __EXPORT_SYMBOL
-#define __EXPORT_SYMBOL(sym, sec)                              \
-       __EXPORT_SYMBOL_NS(sym, sec, DEFAULT_SYMBOL_NAMESPACE)
+#include <linux/stringify.h>
+#define _EXPORT_SYMBOL(sym, sec)       __EXPORT_SYMBOL(sym, sec, __stringify(DEFAULT_SYMBOL_NAMESPACE))
+#else
+#define _EXPORT_SYMBOL(sym, sec)       __EXPORT_SYMBOL(sym, sec, "")
 #endif
 
-#define EXPORT_SYMBOL(sym)             __EXPORT_SYMBOL(sym, "")
-#define EXPORT_SYMBOL_GPL(sym)         __EXPORT_SYMBOL(sym, "_gpl")
-#define EXPORT_SYMBOL_GPL_FUTURE(sym)  __EXPORT_SYMBOL(sym, "_gpl_future")
-#define EXPORT_SYMBOL_NS(sym, ns)      __EXPORT_SYMBOL_NS(sym, "", ns)
-#define EXPORT_SYMBOL_NS_GPL(sym, ns)  __EXPORT_SYMBOL_NS(sym, "_gpl", ns)
+#define EXPORT_SYMBOL(sym)             _EXPORT_SYMBOL(sym, "")
+#define EXPORT_SYMBOL_GPL(sym)         _EXPORT_SYMBOL(sym, "_gpl")
+#define EXPORT_SYMBOL_GPL_FUTURE(sym)  _EXPORT_SYMBOL(sym, "_gpl_future")
+#define EXPORT_SYMBOL_NS(sym, ns)      __EXPORT_SYMBOL(sym, "", #ns)
+#define EXPORT_SYMBOL_NS_GPL(sym, ns)  __EXPORT_SYMBOL(sym, "_gpl", #ns)
 
 #ifdef CONFIG_UNUSED_SYMBOLS
-#define EXPORT_UNUSED_SYMBOL(sym)      __EXPORT_SYMBOL(sym, "_unused")
-#define EXPORT_UNUSED_SYMBOL_GPL(sym)  __EXPORT_SYMBOL(sym, "_unused_gpl")
+#define EXPORT_UNUSED_SYMBOL(sym)      _EXPORT_SYMBOL(sym, "_unused")
+#define EXPORT_UNUSED_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_unused_gpl")
 #else
 #define EXPORT_UNUSED_SYMBOL(sym)
 #define EXPORT_UNUSED_SYMBOL_GPL(sym)
index 1b1e8b8..345f374 100644 (file)
@@ -420,7 +420,7 @@ static inline bool insn_is_zext(const struct bpf_insn *insn)
 
 #define BPF_FIELD_SIZEOF(type, field)                          \
        ({                                                      \
-               const int __size = bytes_to_bpf_size(FIELD_SIZEOF(type, field)); \
+               const int __size = bytes_to_bpf_size(sizeof_field(type, field)); \
                BUILD_BUG_ON(__size < 0);                       \
                __size;                                         \
        })
@@ -497,7 +497,7 @@ static inline bool insn_is_zext(const struct bpf_insn *insn)
 
 #define bpf_target_off(TYPE, MEMBER, SIZE, PTR_SIZE)                           \
        ({                                                                      \
-               BUILD_BUG_ON(FIELD_SIZEOF(TYPE, MEMBER) != (SIZE));             \
+               BUILD_BUG_ON(sizeof_field(TYPE, MEMBER) != (SIZE));             \
                *(PTR_SIZE) = (SIZE);                                           \
                offsetof(TYPE, MEMBER);                                         \
        })
@@ -608,7 +608,7 @@ static inline void bpf_compute_data_pointers(struct sk_buff *skb)
 {
        struct bpf_skb_data_end *cb = (struct bpf_skb_data_end *)skb->cb;
 
-       BUILD_BUG_ON(sizeof(*cb) > FIELD_SIZEOF(struct sk_buff, cb));
+       BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb));
        cb->data_meta = skb->data - skb_metadata_len(skb);
        cb->data_end  = skb->data + skb_headlen(skb);
 }
@@ -646,9 +646,9 @@ static inline u8 *bpf_skb_cb(struct sk_buff *skb)
         * attached to sockets, we need to clear the bpf_skb_cb() area
         * to not leak previous contents to user space.
         */
-       BUILD_BUG_ON(FIELD_SIZEOF(struct __sk_buff, cb) != BPF_SKB_CB_LEN);
-       BUILD_BUG_ON(FIELD_SIZEOF(struct __sk_buff, cb) !=
-                    FIELD_SIZEOF(struct qdisc_skb_cb, data));
+       BUILD_BUG_ON(sizeof_field(struct __sk_buff, cb) != BPF_SKB_CB_LEN);
+       BUILD_BUG_ON(sizeof_field(struct __sk_buff, cb) !=
+                    sizeof_field(struct qdisc_skb_cb, data));
 
        return qdisc_skb_cb(skb)->data;
 }
@@ -776,8 +776,12 @@ bpf_ctx_narrow_access_offset(u32 off, u32 size, u32 size_default)
 
 static inline void bpf_prog_lock_ro(struct bpf_prog *fp)
 {
-       set_vm_flush_reset_perms(fp);
-       set_memory_ro((unsigned long)fp, fp->pages);
+#ifndef CONFIG_BPF_JIT_ALWAYS_ON
+       if (!fp->jited) {
+               set_vm_flush_reset_perms(fp);
+               set_memory_ro((unsigned long)fp, fp->pages);
+       }
+#endif
 }
 
 static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
index 7613bf7..6669e2a 100644 (file)
@@ -16,11 +16,14 @@ enum {
 
 struct meson_sm_firmware;
 
-int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, u32 arg1,
-                 u32 arg2, u32 arg3, u32 arg4);
-int meson_sm_call_write(void *buffer, unsigned int b_size, unsigned int cmd_index,
-                       u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
-int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
-                      u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
+                 u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+                       unsigned int b_size, unsigned int cmd_index, u32 arg0,
+                       u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
+                      unsigned int bsize, unsigned int cmd_index, u32 arg0,
+                      u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+struct meson_sm_firmware *meson_sm_get(struct device_node *firmware_node);
 
 #endif /* _MESON_SM_FW_H_ */
index df366f1..e41ad9e 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Xilinx Zynq MPSoC Firmware layer
  *
- *  Copyright (C) 2014-2018 Xilinx
+ *  Copyright (C) 2014-2019 Xilinx
  *
  *  Michal Simek <michal.simek@xilinx.com>
  *  Davorin Mista <davorin.mista@aggios.com>
@@ -46,6 +46,7 @@
 #define        ZYNQMP_PM_CAPABILITY_ACCESS     0x1U
 #define        ZYNQMP_PM_CAPABILITY_CONTEXT    0x2U
 #define        ZYNQMP_PM_CAPABILITY_WAKEUP     0x4U
+#define        ZYNQMP_PM_CAPABILITY_UNUSABLE   0x8U
 
 /*
  * Firmware FPGA Manager flags
index 7247d35..db95244 100644 (file)
@@ -264,6 +264,7 @@ int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
                                struct dyn_ftrace *rec,
                                unsigned long old_addr,
                                unsigned long new_addr);
+unsigned long ftrace_find_rec_direct(unsigned long ip);
 #else
 # define ftrace_direct_func_count 0
 static inline int register_ftrace_direct(unsigned long ip, unsigned long addr)
@@ -290,6 +291,10 @@ static inline int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
 {
        return -ENODEV;
 }
+static inline unsigned long ftrace_find_rec_direct(unsigned long ip)
+{
+       return 0;
+}
 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
 
 #ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
index 4bd583b..5b14a0f 100644 (file)
@@ -206,7 +206,7 @@ extern struct gen_pool *devm_gen_pool_create(struct device *dev,
                int min_alloc_order, int nid, const char *name);
 extern struct gen_pool *gen_pool_get(struct device *dev, const char *name);
 
-bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start,
+extern bool gen_pool_has_addr(struct gen_pool *pool, unsigned long start,
                        size_t size);
 
 #ifdef CONFIG_OF
index d2f7867..582ef05 100644 (file)
@@ -300,6 +300,7 @@ struct i2c_driver {
  *     generic enough to hide second-sourcing and compatible revisions.
  * @adapter: manages the bus segment hosting this I2C device
  * @dev: Driver model device node for the slave.
+ * @init_irq: IRQ that was set at initialization
  * @irq: indicates the IRQ generated by this device (if any)
  * @detected: member of an i2c_driver.clients list or i2c-core's
  *     userspace_devices list
@@ -466,12 +467,6 @@ i2c_new_probed_device(struct i2c_adapter *adap,
 /* Common custom probe functions */
 extern int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr);
 
-/* For devices that use several addresses, use i2c_new_dummy() to make
- * client handles for the extra addresses.
- */
-extern struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adap, u16 address);
-
 extern struct i2c_client *
 i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address);
 
@@ -856,6 +851,11 @@ extern void i2c_del_driver(struct i2c_driver *driver);
 #define i2c_add_driver(driver) \
        i2c_register_driver(THIS_MODULE, driver)
 
+static inline bool i2c_client_has_driver(struct i2c_client *client)
+{
+       return !IS_ERR_OR_NULL(client) && client->dev.driver;
+}
+
 /* call the i2c_client->command() of all attached clients with
  * the given arguments */
 extern void i2c_clients_command(struct i2c_adapter *adap,
index d77fe34..aa59143 100644 (file)
@@ -28,3 +28,5 @@ extern unsigned int real_root_dev;
 
 extern char __initramfs_start[];
 extern unsigned long __initramfs_size;
+
+void console_on_rootfs(void);
index b76a180..a10e847 100644 (file)
@@ -37,12 +37,35 @@ do {                                                \
        (t)->kcov_mode &= ~KCOV_IN_CTXSW;       \
 } while (0)
 
+/* See Documentation/dev-tools/kcov.rst for usage details. */
+void kcov_remote_start(u64 handle);
+void kcov_remote_stop(void);
+u64 kcov_common_handle(void);
+
+static inline void kcov_remote_start_common(u64 id)
+{
+       kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id));
+}
+
+static inline void kcov_remote_start_usb(u64 id)
+{
+       kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_USB, id));
+}
+
 #else
 
 static inline void kcov_task_init(struct task_struct *t) {}
 static inline void kcov_task_exit(struct task_struct *t) {}
 static inline void kcov_prepare_switch(struct task_struct *t) {}
 static inline void kcov_finish_switch(struct task_struct *t) {}
+static inline void kcov_remote_start(u64 handle) {}
+static inline void kcov_remote_stop(void) {}
+static inline u64 kcov_common_handle(void)
+{
+       return 0;
+}
+static inline void kcov_remote_start_common(u64 id) {}
+static inline void kcov_remote_start_usb(u64 id) {}
 
 #endif /* CONFIG_KCOV */
 #endif /* _LINUX_KCOV_H */
index 09f7592..3adcb39 100644 (file)
@@ -348,8 +348,7 @@ int __must_check kstrtoll(const char *s, unsigned int base, long long *res);
  * @res: Where to write the result of the conversion on success.
  *
  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
- * Used as a replacement for the obsolete simple_strtoull. Return code must
- * be checked.
+ * Used as a replacement for the simple_strtoull. Return code must be checked.
 */
 static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res)
 {
@@ -377,8 +376,7 @@ static inline int __must_check kstrtoul(const char *s, unsigned int base, unsign
  * @res: Where to write the result of the conversion on success.
  *
  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
- * Used as a replacement for the obsolete simple_strtoull. Return code must
- * be checked.
+ * Used as a replacement for the simple_strtoull. Return code must be checked.
  */
 static inline int __must_check kstrtol(const char *s, unsigned int base, long *res)
 {
@@ -454,7 +452,18 @@ static inline int __must_check kstrtos32_from_user(const char __user *s, size_t
        return kstrtoint_from_user(s, count, base, res);
 }
 
-/* Obsolete, do not use.  Use kstrto<foo> instead */
+/*
+ * Use kstrto<foo> instead.
+ *
+ * NOTE: simple_strto<foo> does not check for the range overflow and,
+ *      depending on the input, may give interesting results.
+ *
+ * Use these functions if and only if you cannot use kstrto<foo>, because
+ * the conversion ends on the first non-digit character, which may be far
+ * beyond the supported range. It might be useful to parse the strings like
+ * 10x50 or 12:21 without altering original string or temporary buffer in use.
+ * Keep in mind above caveat.
+ */
 
 extern unsigned long simple_strtoul(const char *,char **,unsigned int);
 extern long simple_strtol(const char *,char **,unsigned int);
index 7ed1e2f..538c25e 100644 (file)
@@ -149,7 +149,7 @@ static inline bool is_error_page(struct page *page)
 #define KVM_REQUEST_ARCH_BASE     8
 
 #define KVM_ARCH_REQ_FLAGS(nr, flags) ({ \
-       BUILD_BUG_ON((unsigned)(nr) >= (FIELD_SIZEOF(struct kvm_vcpu, requests) * 8) - KVM_REQUEST_ARCH_BASE); \
+       BUILD_BUG_ON((unsigned)(nr) >= (sizeof_field(struct kvm_vcpu, requests) * 8) - KVM_REQUEST_ARCH_BASE); \
        (unsigned)(((nr) + KVM_REQUEST_ARCH_BASE) | (flags)); \
 })
 #define KVM_ARCH_REQ(nr)           KVM_ARCH_REQ_FLAGS(nr, 0)
index e536c57..eede2ab 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef LINUX_LOCKD_DEBUG_H
 #define LINUX_LOCKD_DEBUG_H
 
-#ifdef __KERNEL__
-
 #include <linux/sunrpc/debug.h>
 
 /*
@@ -25,8 +23,6 @@
 # define ifdebug(flag)         if (0)
 #endif
 
-#endif /* __KERNEL__ */
-
 /*
  * Debug flags
  */
index d294dde..666f5f3 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef LINUX_LOCKD_LOCKD_H
 #define LINUX_LOCKD_LOCKD_H
 
-#ifdef __KERNEL__
-
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/ipv6.h>
@@ -373,6 +371,4 @@ static inline int nlm_compare_locks(const struct file_lock *fl1,
 
 extern const struct lock_manager_operations nlmsvc_lock_operations;
 
-#endif /* __KERNEL__ */
-
 #endif /* LINUX_LOCKD_LOCKD_H */
index 88e1e63..54945aa 100644 (file)
@@ -108,10 +108,10 @@ void logic_outsl(unsigned long addr, const void *buffer, unsigned int count);
  * area by redefining the macro below.
  */
 #define PIO_INDIRECT_SIZE 0x4000
-#define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE)
 #else
-#define MMIO_UPPER_LIMIT IO_SPACE_LIMIT
+#define PIO_INDIRECT_SIZE 0
 #endif /* CONFIG_INDIRECT_PIO */
+#define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE)
 
 struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode);
 unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode,
index 067d146..f8db83a 100644 (file)
 #define TIM_CCER_CC4E  BIT(12) /* Capt/Comp 4  out Ena    */
 #define TIM_CCER_CC4P  BIT(13) /* Capt/Comp 4  Polarity   */
 #define TIM_CCER_CCXE  (BIT(0) | BIT(4) | BIT(8) | BIT(12))
-#define TIM_BDTR_BKE   BIT(12) /* Break input enable      */
-#define TIM_BDTR_BKP   BIT(13) /* Break input polarity    */
+#define TIM_BDTR_BKE(x)        BIT(12 + (x) * 12) /* Break input enable */
+#define TIM_BDTR_BKP(x)        BIT(13 + (x) * 12) /* Break input polarity */
 #define TIM_BDTR_AOE   BIT(14) /* Automatic Output Enable */
 #define TIM_BDTR_MOE   BIT(15) /* Main Output Enable      */
-#define TIM_BDTR_BKF   (BIT(16) | BIT(17) | BIT(18) | BIT(19))
-#define TIM_BDTR_BK2F  (BIT(20) | BIT(21) | BIT(22) | BIT(23))
-#define TIM_BDTR_BK2E  BIT(24) /* Break 2 input enable    */
-#define TIM_BDTR_BK2P  BIT(25) /* Break 2 input polarity  */
+#define TIM_BDTR_BKF(x)        (0xf << (16 + (x) * 4))
 #define TIM_DCR_DBA    GENMASK(4, 0)   /* DMA base addr */
 #define TIM_DCR_DBL    GENMASK(12, 8)  /* DMA burst len */
 
@@ -87,8 +84,7 @@
 #define TIM_CR2_MMS2_SHIFT     20
 #define TIM_SMCR_TS_SHIFT      4
 #define TIM_BDTR_BKF_MASK      0xF
-#define TIM_BDTR_BKF_SHIFT     16
-#define TIM_BDTR_BK2F_SHIFT    20
+#define TIM_BDTR_BKF_SHIFT(x)  (16 + (x) * 4)
 
 enum stm32_timers_dmas {
        STM32_TIMERS_DMA_CH1,
index f61cd12..20c2566 100644 (file)
 #define AT91_MATRIX_DDR_IOSR                   BIT(18)
 #define AT91_MATRIX_NFD0_SELECT                        BIT(24)
 #define AT91_MATRIX_DDR_MP_EN                  BIT(25)
-#define AT91_MATRIX_EBI_NUM_CS                 8
 
 #define AT91_MATRIX_USBPUCR_PUON               BIT(30)
 
index b06b757..becde69 100644 (file)
@@ -33,6 +33,7 @@
 #define SGI_MMTIMER            153
 #define STORE_QUEUE_MINOR      155     /* unused */
 #define I2O_MINOR              166
+#define AGPGART_MINOR          175
 #define HWRNG_MINOR            183
 #define MICROCODE_MINOR                184
 #define IRNET_MINOR            187
index 8b0ef04..c97ea3b 100644 (file)
@@ -1838,12 +1838,12 @@ static inline void mm_dec_nr_ptes(struct mm_struct *mm) {}
 int __pte_alloc(struct mm_struct *mm, pmd_t *pmd);
 int __pte_alloc_kernel(pmd_t *pmd);
 
+#if defined(CONFIG_MMU)
+
 /*
- * The following ifdef needed to get the 4level-fixup.h header to work.
- * Remove it when 4level-fixup.h has been removed.
+ * The following ifdef needed to get the 5level-fixup.h header to work.
+ * Remove it when 5level-fixup.h has been removed.
  */
-#if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK)
-
 #ifndef __ARCH_HAS_5LEVEL_HACK
 static inline p4d_t *p4d_alloc(struct mm_struct *mm, pgd_t *pgd,
                unsigned long address)
@@ -1865,7 +1865,7 @@ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long a
        return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))?
                NULL: pmd_offset(pud, address);
 }
-#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */
+#endif /* CONFIG_MMU */
 
 #if USE_SPLIT_PTE_PTLOCKS
 #if ALLOC_SPLIT_PTLOCKS
index 5ba250d..e5c3e23 100644 (file)
@@ -100,11 +100,11 @@ struct kparam_array
 
 /**
  * module_param - typesafe helper for a module/cmdline parameter
- * @value: the variable to alter, and exposed parameter name.
+ * @name: the variable to alter, and exposed parameter name.
  * @type: the type of the parameter
  * @perm: visibility in sysfs.
  *
- * @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a
+ * @name becomes the module parameter, or (prefixed by KBUILD_MODNAME and a
  * ".") the kernel commandline parameter.  Note that - is changed to _, so
  * the user can use "foo-bar=1" even for variable "foo_bar".
  *
index 397a08a..7fe7b87 100644 (file)
@@ -60,6 +60,7 @@ extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int);
 extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int);
 extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
 extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int);
+extern struct dentry *lookup_positive_unlocked(const char *, struct dentry *, int);
 
 extern int follow_down_one(struct path *);
 extern int follow_down(struct path *);
index cf09235..9ef2038 100644 (file)
@@ -1881,6 +1881,11 @@ struct net_device {
        unsigned char           if_port;
        unsigned char           dma;
 
+       /* Note : dev->mtu is often read without holding a lock.
+        * Writers usually hold RTNL.
+        * It is recommended to use READ_ONCE() to annotate the reads,
+        * and to use WRITE_ONCE() to annotate the writes.
+        */
        unsigned int            mtu;
        unsigned int            min_mtu;
        unsigned int            max_mtu;
index fd59904..82d8fb4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/uidgid.h>
 #include <uapi/linux/nfs4.h>
+#include <linux/sunrpc/msg_prot.h>
 
 enum nfs4_acl_whotype {
        NFS4_ACL_WHO_NAMED = 0,
@@ -539,6 +540,8 @@ enum {
 
        NFSPROC4_CLNT_LOOKUPP,
        NFSPROC4_CLNT_LAYOUTERROR,
+
+       NFSPROC4_CLNT_COPY_NOTIFY,
 };
 
 /* nfs41 types */
@@ -674,4 +677,27 @@ struct nfs4_op_map {
        } u;
 };
 
+struct nfs42_netaddr {
+       char            netid[RPCBIND_MAXNETIDLEN];
+       char            addr[RPCBIND_MAXUADDRLEN + 1];
+       u32             netid_len;
+       u32             addr_len;
+};
+
+enum netloc_type4 {
+       NL4_NAME                = 1,
+       NL4_URL                 = 2,
+       NL4_NETADDR             = 3,
+};
+
+struct nl4_server {
+       enum netloc_type4       nl4_type;
+       union {
+               struct { /* NL4_NAME, NL4_URL */
+                       int     nl4_str_sz;
+                       char    nl4_str[NFS4_OPAQUE_LIMIT + 1];
+               };
+               struct nfs42_netaddr    nl4_addr; /* NL4_NETADDR */
+       } u;
+};
 #endif
index 570a60c..c06b1fd 100644 (file)
@@ -189,13 +189,15 @@ struct nfs_inode {
 
 struct nfs4_copy_state {
        struct list_head        copies;
+       struct list_head        src_copies;
        nfs4_stateid            stateid;
        struct completion       completion;
        uint64_t                count;
        struct nfs_writeverf    verf;
        int                     error;
        int                     flags;
-       struct nfs4_state       *parent_state;
+       struct nfs4_state       *parent_src_state;
+       struct nfs4_state       *parent_dst_state;
 };
 
 /*
index a87fe85..c176f70 100644 (file)
@@ -45,6 +45,9 @@ struct nfs_client {
 #define NFS_CS_INFINITE_SLOTS  3               /* - don't limit TCP slots */
 #define NFS_CS_NO_RETRANS_TIMEOUT      4       /* - Disable retransmit timeouts */
 #define NFS_CS_TSM_POSSIBLE    5               /* - Maybe state migration */
+#define NFS_CS_NOPING          6               /* - don't ping on connect */
+#define NFS_CS_DS              7               /* - Server is a DS */
+#define NFS_CS_REUSEPORT       8               /* - reuse src port on reconnect */
        struct sockaddr_storage cl_addr;        /* server identifier */
        size_t                  cl_addrlen;
        char *                  cl_hostname;    /* hostname of server */
@@ -171,7 +174,7 @@ struct nfs_server {
 
        struct nfs_fsid         fsid;
        __u64                   maxfilesize;    /* maximum file size */
-       struct timespec         time_delta;     /* smallest time granularity */
+       struct timespec64       time_delta;     /* smallest time granularity */
        unsigned long           mount_time;     /* when this fs was mounted */
        struct super_block      *super;         /* VFS super block */
        dev_t                   s_dev;          /* superblock dev numbers */
@@ -276,5 +279,6 @@ struct nfs_server {
 #define NFS_CAP_COPY           (1U << 24)
 #define NFS_CAP_OFFLOAD_CANCEL (1U << 25)
 #define NFS_CAP_LAYOUTERROR    (1U << 26)
+#define NFS_CAP_COPY_NOTIFY    (1U << 27)
 
 #endif
index 9b8324e..72d5695 100644 (file)
@@ -62,14 +62,14 @@ struct nfs_fattr {
        struct nfs_fsid         fsid;
        __u64                   fileid;
        __u64                   mounted_on_fileid;
-       struct timespec         atime;
-       struct timespec         mtime;
-       struct timespec         ctime;
+       struct timespec64       atime;
+       struct timespec64       mtime;
+       struct timespec64       ctime;
        __u64                   change_attr;    /* NFSv4 change attribute */
        __u64                   pre_change_attr;/* pre-op NFSv4 change attribute */
        __u64                   pre_size;       /* pre_op_attr.size       */
-       struct timespec         pre_mtime;      /* pre_op_attr.mtime      */
-       struct timespec         pre_ctime;      /* pre_op_attr.ctime      */
+       struct timespec64       pre_mtime;      /* pre_op_attr.mtime      */
+       struct timespec64       pre_ctime;      /* pre_op_attr.ctime      */
        unsigned long           time_start;
        unsigned long           gencount;
        struct nfs4_string      *owner_name;
@@ -143,7 +143,7 @@ struct nfs_fsinfo {
        __u32                   wtmult; /* writes should be multiple of this */
        __u32                   dtpref; /* pref. readdir transfer size */
        __u64                   maxfilesize;
-       struct timespec         time_delta; /* server time granularity */
+       struct timespec64       time_delta; /* server time granularity */
        __u32                   lease_time; /* in seconds */
        __u32                   nlayouttypes; /* number of layouttypes */
        __u32                   layouttype[NFS_MAX_LAYOUT_TYPES]; /* supported pnfs layout driver */
@@ -869,7 +869,7 @@ struct nfs3_sattrargs {
        struct nfs_fh *         fh;
        struct iattr *          sattr;
        unsigned int            guard;
-       struct timespec         guardtime;
+       struct timespec64       guardtime;
 };
 
 struct nfs3_diropargs {
@@ -1435,6 +1435,7 @@ struct nfs42_copy_args {
 
        u64                             count;
        bool                            sync;
+       struct nl4_server               *cp_src;
 };
 
 struct nfs42_write_res {
@@ -1463,6 +1464,22 @@ struct nfs42_offload_status_res {
        int                             osr_status;
 };
 
+struct nfs42_copy_notify_args {
+       struct nfs4_sequence_args       cna_seq_args;
+
+       struct nfs_fh           *cna_src_fh;
+       nfs4_stateid            cna_src_stateid;
+       struct nl4_server       cna_dst;
+};
+
+struct nfs42_copy_notify_res {
+       struct nfs4_sequence_res        cnr_seq_res;
+
+       struct nfstime4         cnr_lease_time;
+       nfs4_stateid            cnr_stateid;
+       struct nl4_server       cnr_src;
+};
+
 struct nfs42_seek_args {
        struct nfs4_sequence_args       seq_args;
 
index 0096a05..0189476 100644 (file)
@@ -150,10 +150,6 @@ extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
 extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
                struct notifier_block *nb);
 
-extern int blocking_notifier_chain_cond_register(
-               struct blocking_notifier_head *nh,
-               struct notifier_block *nb);
-
 extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
                struct notifier_block *nb);
 extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
index 10f8162..6d0d70f 100644 (file)
@@ -270,6 +270,8 @@ struct nvme_fc_remote_port {
  *
  * Host/Initiator Transport Entrypoints/Parameters:
  *
+ * @module:  The LLDD module using the interface
+ *
  * @localport_delete:  The LLDD initiates deletion of a localport via
  *       nvme_fc_deregister_localport(). However, the teardown is
  *       asynchronous. This routine is called upon the completion of the
@@ -383,6 +385,8 @@ struct nvme_fc_remote_port {
  *       Value is Mandatory. Allowed to be zero.
  */
 struct nvme_fc_port_template {
+       struct module   *module;
+
        /* initiator-based functions */
        void    (*localport_delete)(struct nvme_fc_local_port *);
        void    (*remoteport_delete)(struct nvme_fc_remote_port *);
index 3d507a8..5c4d7a7 100644 (file)
@@ -14,7 +14,7 @@ struct phy_device;
 #define PHY_LED_TRIGGER_SPEED_SUFFIX_SIZE      11
 
 #define PHY_LINK_LED_TRIGGER_NAME_SIZE (MII_BUS_ID_SIZE + \
-                                      FIELD_SIZEOF(struct mdio_device, addr)+\
+                                      sizeof_field(struct mdio_device, addr)+\
                                       PHY_LED_TRIGGER_SPEED_SUFFIX_SIZE)
 
 struct phy_led_trigger {
index 44f2245..dbcfa68 100644 (file)
@@ -38,7 +38,6 @@ struct pipe_buffer {
  *     @readers: number of current readers of this pipe
  *     @writers: number of current writers of this pipe
  *     @files: number of struct file referring this pipe (protected by ->i_lock)
- *     @waiting_writers: number of writers blocked waiting for room
  *     @r_counter: reader counter
  *     @w_counter: writer counter
  *     @fasync_readers: reader side fasync
@@ -56,7 +55,6 @@ struct pipe_inode_info {
        unsigned int readers;
        unsigned int writers;
        unsigned int files;
-       unsigned int waiting_writers;
        unsigned int r_counter;
        unsigned int w_counter;
        struct page *tmp_page;
diff --git a/include/linux/platform_data/ti-prm.h b/include/linux/platform_data/ti-prm.h
new file mode 100644 (file)
index 0000000..28154c3
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * TI PRM (Power & Reset Manager) platform data
+ *
+ * Copyright (C) 2019 Texas Instruments, Inc.
+ *
+ * Tero Kristo <t-kristo@ti.com>
+ */
+
+#ifndef _LINUX_PLATFORM_DATA_TI_PRM_H
+#define _LINUX_PLATFORM_DATA_TI_PRM_H
+
+struct clockdomain;
+
+struct ti_prm_platform_data {
+       void (*clkdm_deny_idle)(struct clockdomain *clkdm);
+       void (*clkdm_allow_idle)(struct clockdomain *clkdm);
+       struct clockdomain * (*clkdm_lookup)(const char *name);
+};
+
+#endif /* _LINUX_PLATFORM_DATA_TI_PRM_H */
index b5b7a34..8cfe570 100644 (file)
@@ -49,6 +49,8 @@ struct sysc_regbits {
        s8 emufree_shift;
 };
 
+#define SYSC_QUIRK_FORCE_MSTANDBY      BIT(20)
+#define SYSC_MODULE_QUIRK_AESS         BIT(19)
 #define SYSC_MODULE_QUIRK_SGX          BIT(18)
 #define SYSC_MODULE_QUIRK_HDQ1W                BIT(17)
 #define SYSC_MODULE_QUIRK_I2C          BIT(16)
index ebf5ef1..19eafca 100644 (file)
@@ -34,6 +34,8 @@ enum pm_qos_flags_status {
 #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT    PM_QOS_LATENCY_ANY
 #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS
 #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0
+#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE     0
+#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE     FREQ_QOS_MAX_DEFAULT_VALUE
 #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
 
 #define PM_QOS_FLAG_NO_POWER_OFF       (1 << 0)
@@ -49,21 +51,6 @@ struct pm_qos_flags_request {
        s32 flags;      /* Do not change to 64 bit */
 };
 
-enum dev_pm_qos_req_type {
-       DEV_PM_QOS_RESUME_LATENCY = 1,
-       DEV_PM_QOS_LATENCY_TOLERANCE,
-       DEV_PM_QOS_FLAGS,
-};
-
-struct dev_pm_qos_request {
-       enum dev_pm_qos_req_type type;
-       union {
-               struct plist_node pnode;
-               struct pm_qos_flags_request flr;
-       } data;
-       struct device *dev;
-};
-
 enum pm_qos_type {
        PM_QOS_UNITIALIZED,
        PM_QOS_MAX,             /* return the largest value */
@@ -90,9 +77,51 @@ struct pm_qos_flags {
        s32 effective_flags;    /* Do not change to 64 bit */
 };
 
+
+#define FREQ_QOS_MIN_DEFAULT_VALUE     0
+#define FREQ_QOS_MAX_DEFAULT_VALUE     S32_MAX
+
+enum freq_qos_req_type {
+       FREQ_QOS_MIN = 1,
+       FREQ_QOS_MAX,
+};
+
+struct freq_constraints {
+       struct pm_qos_constraints min_freq;
+       struct blocking_notifier_head min_freq_notifiers;
+       struct pm_qos_constraints max_freq;
+       struct blocking_notifier_head max_freq_notifiers;
+};
+
+struct freq_qos_request {
+       enum freq_qos_req_type type;
+       struct plist_node pnode;
+       struct freq_constraints *qos;
+};
+
+
+enum dev_pm_qos_req_type {
+       DEV_PM_QOS_RESUME_LATENCY = 1,
+       DEV_PM_QOS_LATENCY_TOLERANCE,
+       DEV_PM_QOS_MIN_FREQUENCY,
+       DEV_PM_QOS_MAX_FREQUENCY,
+       DEV_PM_QOS_FLAGS,
+};
+
+struct dev_pm_qos_request {
+       enum dev_pm_qos_req_type type;
+       union {
+               struct plist_node pnode;
+               struct pm_qos_flags_request flr;
+               struct freq_qos_request freq;
+       } data;
+       struct device *dev;
+};
+
 struct dev_pm_qos {
        struct pm_qos_constraints resume_latency;
        struct pm_qos_constraints latency_tolerance;
+       struct freq_constraints freq;
        struct pm_qos_flags flags;
        struct dev_pm_qos_request *resume_latency_req;
        struct dev_pm_qos_request *latency_tolerance_req;
@@ -191,6 +220,10 @@ static inline s32 dev_pm_qos_read_value(struct device *dev,
        switch (type) {
        case DEV_PM_QOS_RESUME_LATENCY:
                return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
+       case DEV_PM_QOS_MIN_FREQUENCY:
+               return PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE;
+       case DEV_PM_QOS_MAX_FREQUENCY:
+               return PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;
        default:
                WARN_ON(1);
                return 0;
@@ -255,27 +288,6 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev)
 }
 #endif
 
-#define FREQ_QOS_MIN_DEFAULT_VALUE     0
-#define FREQ_QOS_MAX_DEFAULT_VALUE     (-1)
-
-enum freq_qos_req_type {
-       FREQ_QOS_MIN = 1,
-       FREQ_QOS_MAX,
-};
-
-struct freq_constraints {
-       struct pm_qos_constraints min_freq;
-       struct blocking_notifier_head min_freq_notifiers;
-       struct pm_qos_constraints max_freq;
-       struct blocking_notifier_head max_freq_notifiers;
-};
-
-struct freq_qos_request {
-       enum freq_qos_req_type type;
-       struct plist_node pnode;
-       struct freq_constraints *qos;
-};
-
 static inline int freq_qos_request_active(struct freq_qos_request *req)
 {
        return !IS_ERR_OR_NULL(req->qos);
@@ -291,6 +303,8 @@ int freq_qos_add_request(struct freq_constraints *qos,
                         enum freq_qos_req_type type, s32 value);
 int freq_qos_update_request(struct freq_qos_request *req, s32 new_value);
 int freq_qos_remove_request(struct freq_qos_request *req);
+int freq_qos_apply(struct freq_qos_request *req,
+                  enum pm_qos_req_action action, s32 value);
 
 int freq_qos_add_notifier(struct freq_constraints *qos,
                          enum freq_qos_req_type type,
index 661efa0..aa3da66 100644 (file)
@@ -63,6 +63,11 @@ struct wakeup_source {
        bool                    autosleep_enabled:1;
 };
 
+#define for_each_wakeup_source(ws) \
+       for ((ws) = wakeup_sources_walk_start();        \
+            (ws);                                      \
+            (ws) = wakeup_sources_walk_next((ws)))
+
 #ifdef CONFIG_PM_SLEEP
 
 /*
@@ -92,6 +97,10 @@ extern void wakeup_source_remove(struct wakeup_source *ws);
 extern struct wakeup_source *wakeup_source_register(struct device *dev,
                                                    const char *name);
 extern void wakeup_source_unregister(struct wakeup_source *ws);
+extern int wakeup_sources_read_lock(void);
+extern void wakeup_sources_read_unlock(int idx);
+extern struct wakeup_source *wakeup_sources_walk_start(void);
+extern struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws);
 extern int device_wakeup_enable(struct device *dev);
 extern int device_wakeup_disable(struct device *dev);
 extern void device_set_wakeup_capable(struct device *dev, bool capable);
index c09d67e..1e6108b 100644 (file)
@@ -302,9 +302,8 @@ extern int kptr_restrict;
        printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_err(fmt, ...) \
        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warning(fmt, ...) \
+#define pr_warn(fmt, ...) \
        printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warn pr_warning
 #define pr_notice(fmt, ...) \
        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_info(fmt, ...) \
index a705aa2..0640be5 100644 (file)
@@ -58,8 +58,8 @@ extern int remove_proc_subtree(const char *, struct proc_dir_entry *);
 struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
                struct proc_dir_entry *parent, const struct seq_operations *ops,
                unsigned int state_size, void *data);
-#define proc_create_net(name, mode, parent, state_size, ops) \
-       proc_create_net_data(name, mode, parent, state_size, ops, NULL)
+#define proc_create_net(name, mode, parent, ops, state_size) \
+       proc_create_net_data(name, mode, parent, ops, state_size, NULL)
 struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
                struct proc_dir_entry *parent,
                int (*show)(struct seq_file *, void *), void *data);
index b2c9c46..0ef808d 100644 (file)
@@ -243,10 +243,7 @@ pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle,
  * @request: optional hook for requesting a PWM
  * @free: optional hook for freeing a PWM
  * @capture: capture and report PWM signal
- * @apply: atomically apply a new PWM config. The state argument
- *        should be adjusted with the real hardware config (if the
- *        approximate the period or duty_cycle value, state should
- *        reflect it)
+ * @apply: atomically apply a new PWM config
  * @get_state: get the current PWM state. This function is only
  *            called once per PWM device when the PWM chip is
  *            registered.
index ffd72b3..d05ddac 100644 (file)
@@ -24,6 +24,26 @@ struct qcom_scm_vmperm {
        int perm;
 };
 
+enum qcom_scm_ocmem_client {
+       QCOM_SCM_OCMEM_UNUSED_ID = 0x0,
+       QCOM_SCM_OCMEM_GRAPHICS_ID,
+       QCOM_SCM_OCMEM_VIDEO_ID,
+       QCOM_SCM_OCMEM_LP_AUDIO_ID,
+       QCOM_SCM_OCMEM_SENSORS_ID,
+       QCOM_SCM_OCMEM_OTHER_OS_ID,
+       QCOM_SCM_OCMEM_DEBUG_ID,
+};
+
+enum qcom_scm_sec_dev_id {
+       QCOM_SCM_MDSS_DEV_ID    = 1,
+       QCOM_SCM_OCMEM_DEV_ID   = 5,
+       QCOM_SCM_PCIE0_DEV_ID   = 11,
+       QCOM_SCM_PCIE1_DEV_ID   = 12,
+       QCOM_SCM_GFX_DEV_ID     = 18,
+       QCOM_SCM_UFS_DEV_ID     = 19,
+       QCOM_SCM_ICE_DEV_ID     = 20,
+};
+
 #define QCOM_SCM_VMID_HLOS       0x3
 #define QCOM_SCM_VMID_MSS_MSA    0xF
 #define QCOM_SCM_VMID_WLAN       0x18
@@ -41,6 +61,11 @@ 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_ocmem_lock_available(void);
+extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
+                              u32 size, u32 mode);
+extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset,
+                                u32 size);
 extern bool qcom_scm_pas_supported(u32 peripheral);
 extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
                                   size_t size);
@@ -55,6 +80,7 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 extern void qcom_scm_cpu_power_down(u32 flags);
 extern u32 qcom_scm_get_version(void);
 extern int qcom_scm_set_remote_state(u32 state, u32 id);
+extern bool qcom_scm_restore_sec_cfg_available(void);
 extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
 extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
 extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
index fdd421b..724b0d0 100644 (file)
@@ -283,14 +283,12 @@ __rb_erase_augmented(struct rb_node *node, struct rb_root *root,
                __rb_change_child(node, successor, tmp, root);
 
                if (child2) {
-                       successor->__rb_parent_color = pc;
                        rb_set_parent_color(child2, parent, RB_BLACK);
                        rebalance = NULL;
                } else {
-                       unsigned long pc2 = successor->__rb_parent_color;
-                       successor->__rb_parent_color = pc;
-                       rebalance = __rb_is_black(pc2) ? parent : NULL;
+                       rebalance = rb_is_black(successor) ? parent : NULL;
                }
+               successor->__rb_parent_color = pc;
                tmp = successor;
        }
 
index eaae6b4..ec35814 100644 (file)
@@ -62,7 +62,8 @@ struct reset_control_lookup {
  * @of_node: corresponding device tree node as phandle target
  * @of_reset_n_cells: number of cells in reset line specifiers
  * @of_xlate: translation function to translate from specifier as found in the
- *            device tree to id as given to the reset control ops
+ *            device tree to id as given to the reset control ops, defaults
+ *            to :c:func:`of_reset_simple_xlate`.
  * @nr_resets: number of reset controls in this reset controller device
  */
 struct reset_controller_dev {
index eb597e8..05aa9f4 100644 (file)
@@ -203,12 +203,34 @@ static inline struct reset_control *reset_control_get_shared(
        return __reset_control_get(dev, id, 0, true, false, false);
 }
 
+/**
+ * reset_control_get_optional_exclusive - optional reset_control_get_exclusive()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Optional variant of reset_control_get_exclusive(). If the requested reset
+ * is not specified in the device tree, this function returns NULL instead of
+ * an error.
+ *
+ * See reset_control_get_exclusive() for more information.
+ */
 static inline struct reset_control *reset_control_get_optional_exclusive(
                                        struct device *dev, const char *id)
 {
        return __reset_control_get(dev, id, 0, false, true, true);
 }
 
+/**
+ * reset_control_get_optional_shared - optional reset_control_get_shared()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Optional variant of reset_control_get_shared(). If the requested reset
+ * is not specified in the device tree, this function returns NULL instead of
+ * an error.
+ *
+ * See reset_control_get_shared() for more information.
+ */
 static inline struct reset_control *reset_control_get_optional_shared(
                                        struct device *dev, const char *id)
 {
@@ -354,12 +376,36 @@ static inline struct reset_control *devm_reset_control_get_shared(
        return __devm_reset_control_get(dev, id, 0, true, false, false);
 }
 
+/**
+ * devm_reset_control_get_optional_exclusive - resource managed
+ *                                             reset_control_get_optional_exclusive()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Managed reset_control_get_optional_exclusive(). For reset controllers
+ * returned from this function, reset_control_put() is called automatically on
+ * driver detach.
+ *
+ * See reset_control_get_optional_exclusive() for more information.
+ */
 static inline struct reset_control *devm_reset_control_get_optional_exclusive(
                                        struct device *dev, const char *id)
 {
        return __devm_reset_control_get(dev, id, 0, false, true, true);
 }
 
+/**
+ * devm_reset_control_get_optional_shared - resource managed
+ *                                          reset_control_get_optional_shared()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Managed reset_control_get_optional_shared(). For reset controllers returned
+ * from this function, reset_control_put() is called automatically on driver
+ * detach.
+ *
+ * See reset_control_get_optional_shared() for more information.
+ */
 static inline struct reset_control *devm_reset_control_get_optional_shared(
                                        struct device *dev, const char *id)
 {
index 0cd97d9..467d260 100644 (file)
@@ -1210,6 +1210,8 @@ struct task_struct {
 #endif /* CONFIG_TRACING */
 
 #ifdef CONFIG_KCOV
+       /* See kernel/kcov.c for more details. */
+
        /* Coverage collection mode enabled for this task (0 if disabled): */
        unsigned int                    kcov_mode;
 
@@ -1221,6 +1223,12 @@ struct task_struct {
 
        /* KCOV descriptor wired with this task or NULL: */
        struct kcov                     *kcov;
+
+       /* KCOV common handle for remote coverage collection: */
+       u64                             kcov_handle;
+
+       /* KCOV sequence number: */
+       int                             kcov_sequence;
 #endif
 
 #ifdef CONFIG_MEMCG
index 7af5bec..e9133bc 100644 (file)
@@ -3529,8 +3529,9 @@ int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci);
 int skb_vlan_pop(struct sk_buff *skb);
 int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);
 int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto,
-                 int mac_len);
-int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len);
+                 int mac_len, bool ethernet);
+int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len,
+                bool ethernet);
 int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse);
 int skb_mpls_dec_ttl(struct sk_buff *skb);
 struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy,
similarity index 70%
rename from arch/arm/mach-mmp/cputype.h
rename to include/linux/soc/mmp/cputype.h
index a96abcf..2217907 100644 (file)
@@ -2,7 +2,9 @@
 #ifndef __ASM_MACH_CPUTYPE_H
 #define __ASM_MACH_CPUTYPE_H
 
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
 #include <asm/cputype.h>
+#endif
 
 /*
  *  CPU   Stepping   CPU_ID      CHIP_ID
@@ -18,6 +20,8 @@
  * MMP2             Z0    0x560f5811   0x00F00410
  * MMP2      Z1    0x560f5811   0x00E00410
  * MMP2      A0    0x560f5811   0x00A0A610
+ * MMP3      A0    0x562f5842   0x00A02128
+ * MMP3      B0    0x562f5842   0x00B02128
  */
 
 extern unsigned int mmp_chip_id;
@@ -55,4 +59,29 @@ static inline int cpu_is_mmp2(void)
 #define cpu_is_mmp2()  (0)
 #endif
 
+#ifdef CONFIG_MACH_MMP3_DT
+static inline int cpu_is_mmp3(void)
+{
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x58) &&
+               ((mmp_chip_id & 0xffff) == 0x2128);
+}
+
+static inline int cpu_is_mmp3_a0(void)
+{
+       return (cpu_is_mmp3() &&
+               ((mmp_chip_id & 0x00ff0000) == 0x00a00000));
+}
+
+static inline int cpu_is_mmp3_b0(void)
+{
+       return (cpu_is_mmp3() &&
+               ((mmp_chip_id & 0x00ff0000) == 0x00b00000));
+}
+
+#else
+#define cpu_is_mmp3()          (0)
+#define cpu_is_mmp3_a0()       (0)
+#define cpu_is_mmp3_b0()       (0)
+#endif
+
 #endif /* __ASM_MACH_CPUTYPE_H */
index eb71a50..90b8646 100644 (file)
@@ -38,33 +38,27 @@ struct llcc_slice_desc {
 };
 
 /**
- * llcc_slice_config - Data associated with the llcc slice
- * @usecase_id: usecase id for which the llcc slice is used
- * @slice_id: llcc slice id assigned to each slice
- * @max_cap: maximum capacity of the llcc slice
- * @priority: priority of the llcc slice
- * @fixed_size: whether the llcc slice can grow beyond its size
- * @bonus_ways: bonus ways associated with llcc slice
- * @res_ways: reserved ways associated with llcc slice
- * @cache_mode: mode of the llcc slice
- * @probe_target_ways: Probe only reserved and bonus ways on a cache miss
- * @dis_cap_alloc: Disable capacity based allocation
- * @retain_on_pc: Retain through power collapse
- * @activate_on_init: activate the slice on init
+ * llcc_edac_reg_data - llcc edac registers data for each error type
+ * @name: Name of the error
+ * @synd_reg: Syndrome register address
+ * @count_status_reg: Status register address to read the error count
+ * @ways_status_reg: Status register address to read the error ways
+ * @reg_cnt: Number of registers
+ * @count_mask: Mask value to get the error count
+ * @ways_mask: Mask value to get the error ways
+ * @count_shift: Shift value to get the error count
+ * @ways_shift: Shift value to get the error ways
  */
-struct llcc_slice_config {
-       u32 usecase_id;
-       u32 slice_id;
-       u32 max_cap;
-       u32 priority;
-       bool fixed_size;
-       u32 bonus_ways;
-       u32 res_ways;
-       u32 cache_mode;
-       u32 probe_target_ways;
-       bool dis_cap_alloc;
-       bool retain_on_pc;
-       bool activate_on_init;
+struct llcc_edac_reg_data {
+       char *name;
+       u64 synd_reg;
+       u64 count_status_reg;
+       u64 ways_status_reg;
+       u32 reg_cnt;
+       u32 count_mask;
+       u32 ways_mask;
+       u8  count_shift;
+       u8  ways_shift;
 };
 
 /**
@@ -93,30 +87,6 @@ struct llcc_drv_data {
        int ecc_irq;
 };
 
-/**
- * llcc_edac_reg_data - llcc edac registers data for each error type
- * @name: Name of the error
- * @synd_reg: Syndrome register address
- * @count_status_reg: Status register address to read the error count
- * @ways_status_reg: Status register address to read the error ways
- * @reg_cnt: Number of registers
- * @count_mask: Mask value to get the error count
- * @ways_mask: Mask value to get the error ways
- * @count_shift: Shift value to get the error count
- * @ways_shift: Shift value to get the error ways
- */
-struct llcc_edac_reg_data {
-       char *name;
-       u64 synd_reg;
-       u64 count_status_reg;
-       u64 ways_status_reg;
-       u32 reg_cnt;
-       u32 count_mask;
-       u32 ways_mask;
-       u8  count_shift;
-       u8  ways_shift;
-};
-
 #if IS_ENABLED(CONFIG_QCOM_LLCC)
 /**
  * llcc_slice_getd - get llcc slice descriptor
@@ -154,20 +124,6 @@ int llcc_slice_activate(struct llcc_slice_desc *desc);
  */
 int llcc_slice_deactivate(struct llcc_slice_desc *desc);
 
-/**
- * qcom_llcc_probe - program the sct table
- * @pdev: platform device pointer
- * @table: soc sct table
- * @sz: Size of the config table
- */
-int qcom_llcc_probe(struct platform_device *pdev,
-                     const struct llcc_slice_config *table, u32 sz);
-
-/**
- * qcom_llcc_remove - remove the sct table
- * @pdev: Platform device pointer
- */
-int qcom_llcc_remove(struct platform_device *pdev);
 #else
 static inline struct llcc_slice_desc *llcc_slice_getd(u32 uid)
 {
@@ -197,16 +153,6 @@ static inline int llcc_slice_deactivate(struct llcc_slice_desc *desc)
 {
        return -EINVAL;
 }
-static inline int qcom_llcc_probe(struct platform_device *pdev,
-                     const struct llcc_slice_config *table, u32 sz)
-{
-       return -ENODEV;
-}
-
-static inline int qcom_llcc_remove(struct platform_device *pdev)
-{
-       return -ENODEV;
-}
 #endif
 
 #endif
index 4bde630..2d23134 100644 (file)
@@ -378,12 +378,19 @@ extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
 extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
                          unsigned int vlen, unsigned int flags,
                          bool forbid_cmsg_compat);
-extern long __sys_sendmsg_sock(struct socket *sock,
-                              struct user_msghdr __user *msg,
+extern long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
                               unsigned int flags);
-extern long __sys_recvmsg_sock(struct socket *sock,
-                              struct user_msghdr __user *msg,
+extern long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
+                              struct user_msghdr __user *umsg,
+                              struct sockaddr __user *uaddr,
                               unsigned int flags);
+extern int sendmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct iovec **iov);
+extern int recvmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct sockaddr __user **uaddr,
+                              struct iovec **iov);
 
 /* helpers which do the actual work for syscalls */
 extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
@@ -399,9 +406,8 @@ extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
                         int __user *upeer_addrlen, int flags);
 extern int __sys_socket(int family, int type, int protocol);
 extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
-extern int __sys_connect_file(struct file *file,
-                       struct sockaddr __user *uservaddr, int addrlen,
-                       int file_flags);
+extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr,
+                             int addrlen, int file_flags);
 extern int __sys_connect(int fd, struct sockaddr __user *uservaddr,
                         int addrlen);
 extern int __sys_listen(int fd, int backlog);
index 5f9076f..e9ec742 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef _LINUX_SUNRPC_AUTH_H
 #define _LINUX_SUNRPC_AUTH_H
 
-#ifdef __KERNEL__
-
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/msg_prot.h>
 #include <linux/sunrpc/xdr.h>
@@ -194,5 +192,4 @@ struct rpc_cred *get_rpccred(struct rpc_cred *cred)
        return NULL;
 }
 
-#endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_AUTH_H */
index 30427b7..43e481a 100644 (file)
@@ -13,7 +13,6 @@
 #ifndef _LINUX_SUNRPC_AUTH_GSS_H
 #define _LINUX_SUNRPC_AUTH_GSS_H
 
-#ifdef __KERNEL__
 #include <linux/refcount.h>
 #include <linux/sunrpc/auth.h>
 #include <linux/sunrpc/svc.h>
@@ -90,6 +89,5 @@ struct gss_cred {
        unsigned long           gc_upcall_timestamp;
 };
 
-#endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_AUTH_GSS_H */
 
index abc63bd..ca7e108 100644 (file)
@@ -109,8 +109,6 @@ struct rpc_procinfo {
        const char *            p_name;         /* name of procedure */
 };
 
-#ifdef __KERNEL__
-
 struct rpc_create_args {
        struct net              *net;
        int                     protocol;
@@ -149,6 +147,7 @@ struct rpc_add_xprt_test {
 #define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT        (1UL << 8)
 #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT     (1UL << 9)
 #define RPC_CLNT_CREATE_SOFTERR                (1UL << 10)
+#define RPC_CLNT_CREATE_REUSEPORT      (1UL << 11)
 
 struct rpc_clnt *rpc_create(struct rpc_create_args *args);
 struct rpc_clnt        *rpc_bind_new_program(struct rpc_clnt *,
@@ -237,5 +236,4 @@ static inline int rpc_reply_expected(struct rpc_task *task)
                (task->tk_msg.rpc_proc->p_decode != NULL);
 }
 
-#endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_CLNT_H */
index 5ac5db4..bd691e0 100644 (file)
@@ -13,7 +13,6 @@
 #ifndef _LINUX_SUNRPC_GSS_API_H
 #define _LINUX_SUNRPC_GSS_API_H
 
-#ifdef __KERNEL__
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/msg_prot.h>
 #include <linux/uio.h>
@@ -160,6 +159,5 @@ struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
  * corresponding call to gss_mech_put. */
 void gss_mech_put(struct gss_api_mech *);
 
-#endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_GSS_API_H */
 
index a680786..b73c329 100644 (file)
@@ -34,8 +34,6 @@
 #ifndef _LINUX_SUNRPC_GSS_ERR_H
 #define _LINUX_SUNRPC_GSS_ERR_H
 
-#ifdef __KERNEL__
-
 typedef unsigned int OM_uint32;
 
 /*
@@ -163,5 +161,4 @@ typedef unsigned int OM_uint32;
 /* XXXX This is a necessary evil until the spec is fixed */
 #define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
 
-#endif /* __KERNEL__ */
 #endif /* __LINUX_SUNRPC_GSS_ERR_H */
index 4722b28..bea40d9 100644 (file)
@@ -8,8 +8,6 @@
 #ifndef _LINUX_SUNRPC_MSGPROT_H_
 #define _LINUX_SUNRPC_MSGPROT_H_
 
-#ifdef __KERNEL__ /* user programs should get these from the rpc header files */
-
 #define RPC_VERSION 2
 
 /* size of an XDR encoding unit in bytes, i.e. 32bit */
@@ -217,5 +215,4 @@ typedef __be32      rpc_fraghdr;
 /* Assume INET6_ADDRSTRLEN will always be larger than INET_ADDRSTRLEN... */
 #define RPCBIND_MAXUADDRLEN    RPCBIND_MAXUADDR6LEN
 
-#endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_MSGPROT_H_ */
index e90b9bd..cd188a5 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef _LINUX_SUNRPC_RPC_PIPE_FS_H
 #define _LINUX_SUNRPC_RPC_PIPE_FS_H
 
-#ifdef __KERNEL__
-
 #include <linux/workqueue.h>
 
 struct rpc_pipe_dir_head {
@@ -133,4 +131,3 @@ extern void unregister_rpc_pipefs(void);
 extern bool gssd_running(struct net *net);
 
 #endif
-#endif
index 3e53a6e..b000386 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef _LINUX_SUNRPC_SVCAUTH_H_
 #define _LINUX_SUNRPC_SVCAUTH_H_
 
-#ifdef __KERNEL__
-
 #include <linux/string.h>
 #include <linux/sunrpc/msg_prot.h>
 #include <linux/sunrpc/cache.h>
@@ -185,6 +183,4 @@ static inline unsigned long hash_mem(char const *buf, int length, int bits)
        return full_name_hash(NULL, buf, length) >> (32 - bits);
 }
 
-#endif /* __KERNEL__ */
-
 #endif /* _LINUX_SUNRPC_SVCAUTH_H_ */
index a4528b2..ca39a38 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef _LINUX_SUNRPC_SVCAUTH_GSS_H
 #define _LINUX_SUNRPC_SVCAUTH_GSS_H
 
-#ifdef __KERNEL__
 #include <linux/sched.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
@@ -24,5 +23,4 @@ void gss_svc_shutdown_net(struct net *net);
 int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
 u32 svcauth_gss_flavor(struct auth_domain *dom);
 
-#endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
index f33e501..b41f349 100644 (file)
@@ -11,8 +11,6 @@
 #ifndef _SUNRPC_XDR_H_
 #define _SUNRPC_XDR_H_
 
-#ifdef __KERNEL__
-
 #include <linux/uio.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
@@ -552,6 +550,5 @@ xdr_stream_decode_uint32_array(struct xdr_stream *xdr,
                *array = be32_to_cpup(p);
        return retval;
 }
-#endif /* __KERNEL__ */
 
 #endif /* _SUNRPC_XDR_H_ */
index d783e15..e64bd82 100644 (file)
@@ -19,8 +19,6 @@
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/msg_prot.h>
 
-#ifdef __KERNEL__
-
 #define RPC_MIN_SLOT_TABLE     (2U)
 #define RPC_DEF_SLOT_TABLE     (16U)
 #define RPC_MAX_SLOT_TABLE_LIMIT       (65536U)
@@ -207,7 +205,8 @@ struct rpc_xprt {
        unsigned int            min_reqs;       /* min number of slots */
        unsigned int            num_reqs;       /* total slots */
        unsigned long           state;          /* transport state */
-       unsigned char           resvport   : 1; /* use a reserved port */
+       unsigned char           resvport   : 1, /* use a reserved port */
+                               reuseport  : 1; /* reuse port on reconnect */
        atomic_t                swapper;        /* we're swapping over this
                                                   transport */
        unsigned int            bind_index;     /* bind function index */
@@ -505,6 +504,4 @@ static inline void xprt_inject_disconnect(struct rpc_xprt *xprt)
 }
 #endif
 
-#endif /* __KERNEL__*/
-
 #endif /* _LINUX_SUNRPC_XPRT_H */
index a940de0..3c1423e 100644 (file)
@@ -8,8 +8,6 @@
 #ifndef _LINUX_SUNRPC_XPRTSOCK_H
 #define _LINUX_SUNRPC_XPRTSOCK_H
 
-#ifdef __KERNEL__
-
 int            init_socket_xprt(void);
 void           cleanup_socket_xprt(void);
 
@@ -91,6 +89,4 @@ struct sock_xprt {
 #define XPRT_SOCK_WAKE_PENDING (6)
 #define XPRT_SOCK_WAKE_DISCONNECT      (7)
 
-#endif /* __KERNEL__ */
-
 #endif /* _LINUX_SUNRPC_XPRTSOCK_H */
index d0391cc..2960ded 100644 (file)
@@ -1231,10 +1231,7 @@ asmlinkage long sys_ni_syscall(void);
  * the ksys_xyzyyz() functions prototyped below.
  */
 
-int ksys_mount(const char __user *dev_name, const char __user *dir_name,
-              const char __user *type, unsigned long flags, void __user *data);
 int ksys_umount(char __user *name, int flags);
-int ksys_dup(unsigned int fildes);
 int ksys_chroot(const char __user *filename);
 ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count);
 int ksys_chdir(const char __user *filename);
index 6df4773..02fa844 100644 (file)
@@ -120,8 +120,7 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)
        struct ctl_table_poll name = __CTL_TABLE_POLL_INITIALIZER(name)
 
 /* A sysctl table is an array of struct ctl_table: */
-struct ctl_table 
-{
+struct ctl_table {
        const char *procname;           /* Text ID for /proc/sys, or zero */
        void *data;
        int maxlen;
@@ -140,8 +139,7 @@ struct ctl_node {
 
 /* struct ctl_table_header is used to maintain dynamic lists of
    struct ctl_table trees. */
-struct ctl_table_header
-{
+struct ctl_table_header {
        union {
                struct {
                        struct ctl_table *ctl_table;
index e45659c..d9111ae 100644 (file)
@@ -544,15 +544,4 @@ static inline void thermal_notify_framework(struct thermal_zone_device *tz,
 { }
 #endif /* CONFIG_THERMAL */
 
-#if defined(CONFIG_NET) && IS_ENABLED(CONFIG_THERMAL)
-extern int thermal_generate_netlink_event(struct thermal_zone_device *tz,
-                                               enum events event);
-#else
-static inline int thermal_generate_netlink_event(struct thermal_zone_device *tz,
-                                               enum events event)
-{
-       return 0;
-}
-#endif
-
 #endif /* __THERMAL_H__ */
index 659a440..e93e249 100644 (file)
@@ -147,6 +147,8 @@ check_copy_size(const void *addr, size_t bytes, bool is_source)
                        __bad_copy_to();
                return false;
        }
+       if (WARN_ON_ONCE(bytes > INT_MAX))
+               return false;
        check_object_size(addr, bytes, is_source);
        return true;
 }
index 0760a4f..8e10b9d 100644 (file)
@@ -97,4 +97,17 @@ static inline bool itimerspec64_valid(const struct itimerspec64 *its)
  */
 #define time_after32(a, b)     ((s32)((u32)(b) - (u32)(a)) < 0)
 #define time_before32(b, a)    time_after32(a, b)
+
+/**
+ * time_between32 - check if a 32-bit timestamp is within a given time range
+ * @t: the time which may be within [l,h]
+ * @l: the lower bound of the range
+ * @h: the higher bound of the range
+ *
+ * time_before32(t, l, h) returns true if @l <= @t <= @h. All operands are
+ * treated as 32-bit integers.
+ *
+ * Equivalent to !(time_before32(@t, @l) || time_after32(@t, @h)).
+ */
+#define time_between32(t, l, h) ((u32)(h) - (u32)(l) >= (u32)(t) - (u32)(l))
 #endif
index bdeda4b..292485f 100644 (file)
@@ -31,6 +31,12 @@ struct reclaim_stat {
        unsigned nr_unmap_fail;
 };
 
+enum writeback_stat_item {
+       NR_DIRTY_THRESHOLD,
+       NR_DIRTY_BG_THRESHOLD,
+       NR_VM_WRITEBACK_STAT_ITEMS,
+};
+
 #ifdef CONFIG_VM_EVENT_COUNTERS
 /*
  * Light weight per cpu counter implementation.
@@ -381,4 +387,48 @@ static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages,
 
 extern const char * const vmstat_text[];
 
+static inline const char *zone_stat_name(enum zone_stat_item item)
+{
+       return vmstat_text[item];
+}
+
+#ifdef CONFIG_NUMA
+static inline const char *numa_stat_name(enum numa_stat_item item)
+{
+       return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
+                          item];
+}
+#endif /* CONFIG_NUMA */
+
+static inline const char *node_stat_name(enum node_stat_item item)
+{
+       return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
+                          NR_VM_NUMA_STAT_ITEMS +
+                          item];
+}
+
+static inline const char *lru_list_name(enum lru_list lru)
+{
+       return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
+}
+
+static inline const char *writeback_stat_name(enum writeback_stat_item item)
+{
+       return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
+                          NR_VM_NUMA_STAT_ITEMS +
+                          NR_VM_NODE_STAT_ITEMS +
+                          item];
+}
+
+#if defined(CONFIG_VM_EVENT_COUNTERS) || defined(CONFIG_MEMCG)
+static inline const char *vm_event_name(enum vm_event_item item)
+{
+       return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
+                          NR_VM_NUMA_STAT_ITEMS +
+                          NR_VM_NODE_STAT_ITEMS +
+                          NR_VM_WRITEBACK_STAT_ITEMS +
+                          item];
+}
+#endif /* CONFIG_VM_EVENT_COUNTERS || CONFIG_MEMCG */
+
 #endif /* _LINUX_VMSTAT_H */
index b8c20e9..d93017a 100644 (file)
@@ -235,6 +235,7 @@ enum flow_dissector_key_id {
        FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
        FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
        FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
+       FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
        FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
        FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
        FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
index 86c567f..c6f7bd2 100644 (file)
@@ -380,19 +380,18 @@ static inline void flow_block_init(struct flow_block *flow_block)
 typedef int flow_indr_block_bind_cb_t(struct net_device *dev, void *cb_priv,
                                      enum tc_setup_type type, void *type_data);
 
-typedef void flow_indr_block_ing_cmd_t(struct net_device *dev,
-                                       flow_indr_block_bind_cb_t *cb,
-                                       void *cb_priv,
-                                       enum flow_block_command command);
+typedef void flow_indr_block_cmd_t(struct net_device *dev,
+                                  flow_indr_block_bind_cb_t *cb, void *cb_priv,
+                                  enum flow_block_command command);
 
-struct flow_indr_block_ing_entry {
-       flow_indr_block_ing_cmd_t *cb;
+struct flow_indr_block_entry {
+       flow_indr_block_cmd_t *cb;
        struct list_head        list;
 };
 
-void flow_indr_add_block_ing_cb(struct flow_indr_block_ing_entry *entry);
+void flow_indr_add_block_cb(struct flow_indr_block_entry *entry);
 
-void flow_indr_del_block_ing_cb(struct flow_indr_block_ing_entry *entry);
+void flow_indr_del_block_cb(struct flow_indr_block_entry *entry);
 
 int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv,
                                  flow_indr_block_bind_cb_t *cb,
index c41833b..4d9a0c6 100644 (file)
@@ -37,7 +37,7 @@ struct garp_skb_cb {
 static inline struct garp_skb_cb *garp_cb(struct sk_buff *skb)
 {
        BUILD_BUG_ON(sizeof(struct garp_skb_cb) >
-                    FIELD_SIZEOF(struct sk_buff, cb));
+                    sizeof_field(struct sk_buff, cb));
        return (struct garp_skb_cb *)skb->cb;
 }
 
index 02d68e3..5b317c9 100644 (file)
@@ -760,4 +760,9 @@ int ip_misc_proc_init(void);
 int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family,
                                struct netlink_ext_ack *extack);
 
+static inline bool inetdev_valid_mtu(unsigned int mtu)
+{
+       return likely(mtu >= IPV4_MIN_MTU);
+}
+
 #endif /* _IP_H */
index af64560..236503a 100644 (file)
@@ -33,8 +33,8 @@
 /* Used to memset ipv4 address padding. */
 #define IP_TUNNEL_KEY_IPV4_PAD offsetofend(struct ip_tunnel_key, u.ipv4.dst)
 #define IP_TUNNEL_KEY_IPV4_PAD_LEN                             \
-       (FIELD_SIZEOF(struct ip_tunnel_key, u) -                \
-        FIELD_SIZEOF(struct ip_tunnel_key, u.ipv4))
+       (sizeof_field(struct ip_tunnel_key, u) -                \
+        sizeof_field(struct ip_tunnel_key, u.ipv4))
 
 struct ip_tunnel_key {
        __be64                  tun_id;
@@ -63,7 +63,7 @@ struct ip_tunnel_key {
 
 /* Maximum tunnel options length. */
 #define IP_TUNNEL_OPTS_MAX                                     \
-       GENMASK((FIELD_SIZEOF(struct ip_tunnel_info,            \
+       GENMASK((sizeof_field(struct ip_tunnel_info,            \
                              options_len) * BITS_PER_BYTE) - 1, 0)
 
 struct ip_tunnel_info {
index d04b7ab..4e95f6d 100644 (file)
@@ -1022,7 +1022,7 @@ static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
 
 int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
                   struct flowi6 *fl6);
-struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
+struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6,
                                      const struct in6_addr *final_dst);
 struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
                                         const struct in6_addr *final_dst,
index 5c93e94..3e7d2c0 100644 (file)
@@ -24,8 +24,10 @@ struct ipv6_stub {
                                 const struct in6_addr *addr);
        int (*ipv6_sock_mc_drop)(struct sock *sk, int ifindex,
                                 const struct in6_addr *addr);
-       int (*ipv6_dst_lookup)(struct net *net, struct sock *sk,
-                              struct dst_entry **dst, struct flowi6 *fl6);
+       struct dst_entry *(*ipv6_dst_lookup_flow)(struct net *net,
+                                                 const struct sock *sk,
+                                                 struct flowi6 *fl6,
+                                                 const struct in6_addr *final_dst);
        int (*ipv6_route_input)(struct sk_buff *skb);
 
        struct fib6_table *(*fib6_get_table)(struct net *net, u32 id);
index ef58b4a..1c308c0 100644 (file)
@@ -39,7 +39,7 @@ struct mrp_skb_cb {
 static inline struct mrp_skb_cb *mrp_cb(struct sk_buff *skb)
 {
        BUILD_BUG_ON(sizeof(struct mrp_skb_cb) >
-                    FIELD_SIZEOF(struct sk_buff, cb));
+                    sizeof_field(struct sk_buff, cb));
        return (struct mrp_skb_cb *)skb->cb;
 }
 
index 44b5a00..37f0fbe 100644 (file)
@@ -81,7 +81,7 @@ struct nf_conn_help {
 };
 
 #define NF_CT_HELPER_BUILD_BUG_ON(structsize) \
-       BUILD_BUG_ON((structsize) > FIELD_SIZEOF(struct nf_conn_help, data))
+       BUILD_BUG_ON((structsize) > sizeof_field(struct nf_conn_help, data))
 
 struct nf_conntrack_helper *__nf_conntrack_helper_find(const char *name,
                                                       u16 l3num, u8 protonum);
index 7281895..2656155 100644 (file)
@@ -41,7 +41,7 @@ struct nft_immediate_expr {
  */
 static inline u32 nft_cmp_fast_mask(unsigned int len)
 {
-       return cpu_to_le32(~0U >> (FIELD_SIZEOF(struct nft_cmp_fast_expr,
+       return cpu_to_le32(~0U >> (sizeof_field(struct nft_cmp_fast_expr,
                                                data) * BITS_PER_BYTE - len));
 }
 
index 87d54ef..80f9964 100644 (file)
@@ -2305,7 +2305,7 @@ struct sock_skb_cb {
  * using skb->cb[] would keep using it directly and utilize its
  * alignement guarantee.
  */
-#define SOCK_SKB_CB_OFFSET ((FIELD_SIZEOF(struct sk_buff, cb) - \
+#define SOCK_SKB_CB_OFFSET ((sizeof_field(struct sk_buff, cb) - \
                            sizeof(struct sock_skb_cb)))
 
 #define SOCK_SKB_CB(__skb) ((struct sock_skb_cb *)((__skb)->cb + \
index 36f195f..86b9a87 100644 (file)
@@ -494,15 +494,16 @@ static inline void tcp_synq_overflow(const struct sock *sk)
                reuse = rcu_dereference(sk->sk_reuseport_cb);
                if (likely(reuse)) {
                        last_overflow = READ_ONCE(reuse->synq_overflow_ts);
-                       if (time_after32(now, last_overflow + HZ))
+                       if (!time_between32(now, last_overflow,
+                                           last_overflow + HZ))
                                WRITE_ONCE(reuse->synq_overflow_ts, now);
                        return;
                }
        }
 
-       last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
-       if (time_after32(now, last_overflow + HZ))
-               tcp_sk(sk)->rx_opt.ts_recent_stamp = now;
+       last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp);
+       if (!time_between32(now, last_overflow, last_overflow + HZ))
+               WRITE_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp, now);
 }
 
 /* syncookies: no recent synqueue overflow on this listening socket? */
@@ -517,13 +518,23 @@ static inline bool tcp_synq_no_recent_overflow(const struct sock *sk)
                reuse = rcu_dereference(sk->sk_reuseport_cb);
                if (likely(reuse)) {
                        last_overflow = READ_ONCE(reuse->synq_overflow_ts);
-                       return time_after32(now, last_overflow +
-                                           TCP_SYNCOOKIE_VALID);
+                       return !time_between32(now, last_overflow - HZ,
+                                              last_overflow +
+                                              TCP_SYNCOOKIE_VALID);
                }
        }
 
-       last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
-       return time_after32(now, last_overflow + TCP_SYNCOOKIE_VALID);
+       last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp);
+
+       /* If last_overflow <= jiffies <= last_overflow + TCP_SYNCOOKIE_VALID,
+        * then we're under synflood. However, we have to use
+        * 'last_overflow - HZ' as lower bound. That's because a concurrent
+        * tcp_synq_overflow() could update .ts_recent_stamp after we read
+        * jiffies but before we store .ts_recent_stamp into last_overflow,
+        * which could lead to rejecting a valid syncookie.
+        */
+       return !time_between32(now, last_overflow - HZ,
+                              last_overflow + TCP_SYNCOOKIE_VALID);
 }
 
 static inline u32 tcp_cookie_time(void)
index cacb48f..5608e14 100644 (file)
@@ -2832,6 +2832,11 @@ int rdma_user_mmap_io(struct ib_ucontext *ucontext, struct vm_area_struct *vma,
 int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
                                struct rdma_user_mmap_entry *entry,
                                size_t length);
+int rdma_user_mmap_entry_insert_range(struct ib_ucontext *ucontext,
+                                     struct rdma_user_mmap_entry *entry,
+                                     size_t length, u32 min_pgoff,
+                                     u32 max_pgoff);
+
 struct rdma_user_mmap_entry *
 rdma_user_mmap_entry_get_pgoff(struct ib_ucontext *ucontext,
                               unsigned long pgoff);
diff --git a/include/soc/qcom/ocmem.h b/include/soc/qcom/ocmem.h
new file mode 100644 (file)
index 0000000..02a8bc2
--- /dev/null
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * The On Chip Memory (OCMEM) allocator allows various clients to allocate
+ * memory from OCMEM based on performance, latency and power requirements.
+ * This is typically used by the GPU, camera/video, and audio components on
+ * some Snapdragon SoCs.
+ *
+ * Copyright (C) 2019 Brian Masney <masneyb@onstation.org>
+ * Copyright (C) 2015 Red Hat. Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+
+#ifndef __OCMEM_H__
+#define __OCMEM_H__
+
+enum ocmem_client {
+       /* GMEM clients */
+       OCMEM_GRAPHICS = 0x0,
+       /*
+        * TODO add more once ocmem_allocate() is clever enough to
+        * deal with multiple clients.
+        */
+       OCMEM_CLIENT_MAX,
+};
+
+struct ocmem;
+
+struct ocmem_buf {
+       unsigned long offset;
+       unsigned long addr;
+       unsigned long len;
+};
+
+#if IS_ENABLED(CONFIG_QCOM_OCMEM)
+
+struct ocmem *of_get_ocmem(struct device *dev);
+struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client,
+                                unsigned long size);
+void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
+               struct ocmem_buf *buf);
+
+#else /* IS_ENABLED(CONFIG_QCOM_OCMEM) */
+
+static inline struct ocmem *of_get_ocmem(struct device *dev)
+{
+       return ERR_PTR(-ENODEV);
+}
+
+static inline struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem,
+                                              enum ocmem_client client,
+                                              unsigned long size)
+{
+       return ERR_PTR(-ENODEV);
+}
+
+static inline void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
+                             struct ocmem_buf *buf)
+{
+}
+
+#endif /* IS_ENABLED(CONFIG_QCOM_OCMEM) */
+
+#endif /* __OCMEM_H__ */
index 16e2c2f..1238e35 100644 (file)
@@ -181,7 +181,7 @@ struct tegra_mc {
        spinlock_t lock;
 };
 
-void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
+int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
 unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
 
 #endif /* __SOC_TEGRA_MC_H__ */
index b260c5f..e05b95e 100644 (file)
@@ -493,6 +493,7 @@ struct hdac_stream {
        bool prepared:1;
        bool no_period_wakeup:1;
        bool locked:1;
+       bool stripe:1;                  /* apply stripe control */
 
        /* timestamp */
        unsigned long start_wallclk;    /* start + minimum wallclk */
index d1f7fe1..9827f53 100644 (file)
@@ -126,6 +126,34 @@ DEFINE_GSSAPI_EVENT(verify_mic);
 DEFINE_GSSAPI_EVENT(wrap);
 DEFINE_GSSAPI_EVENT(unwrap);
 
+TRACE_EVENT(rpcgss_accept_upcall,
+       TP_PROTO(
+               __be32 xid,
+               u32 major_status,
+               u32 minor_status
+       ),
+
+       TP_ARGS(xid, major_status, minor_status),
+
+       TP_STRUCT__entry(
+               __field(u32, xid)
+               __field(u32, minor_status)
+               __field(unsigned long, major_status)
+       ),
+
+       TP_fast_assign(
+               __entry->xid = be32_to_cpu(xid);
+               __entry->minor_status = minor_status;
+               __entry->major_status = major_status;
+       ),
+
+       TP_printk("xid=0x%08x major_status=%s (0x%08lx) minor_status=%u",
+               __entry->xid, __entry->major_status == 0 ? "GSS_S_COMPLETE" :
+                               show_gss_status(__entry->major_status),
+               __entry->major_status, __entry->minor_status
+       )
+);
+
 
 /**
  ** GSS auth unwrap failures
@@ -355,6 +383,23 @@ TRACE_EVENT(rpcgss_createauth,
                show_pseudoflavor(__entry->flavor), __entry->error)
 );
 
+TRACE_EVENT(rpcgss_oid_to_mech,
+       TP_PROTO(
+               const char *oid
+       ),
+
+       TP_ARGS(oid),
+
+       TP_STRUCT__entry(
+               __string(oid, oid)
+       ),
+
+       TP_fast_assign(
+               __assign_str(oid, oid);
+       ),
+
+       TP_printk("mech for oid %s was not found", __get_str(oid))
+);
 
 #endif /* _TRACE_RPCGSS_H */
 
index a138306..1879058 100644 (file)
@@ -85,6 +85,44 @@ DECLARE_EVENT_CLASS(xprtrdma_rxprt,
                                ),                                      \
                                TP_ARGS(r_xprt))
 
+DECLARE_EVENT_CLASS(xprtrdma_connect_class,
+       TP_PROTO(
+               const struct rpcrdma_xprt *r_xprt,
+               int rc
+       ),
+
+       TP_ARGS(r_xprt, rc),
+
+       TP_STRUCT__entry(
+               __field(const void *, r_xprt)
+               __field(int, rc)
+               __field(int, connect_status)
+               __string(addr, rpcrdma_addrstr(r_xprt))
+               __string(port, rpcrdma_portstr(r_xprt))
+       ),
+
+       TP_fast_assign(
+               __entry->r_xprt = r_xprt;
+               __entry->rc = rc;
+               __entry->connect_status = r_xprt->rx_ep.rep_connected;
+               __assign_str(addr, rpcrdma_addrstr(r_xprt));
+               __assign_str(port, rpcrdma_portstr(r_xprt));
+       ),
+
+       TP_printk("peer=[%s]:%s r_xprt=%p: rc=%d connect status=%d",
+               __get_str(addr), __get_str(port), __entry->r_xprt,
+               __entry->rc, __entry->connect_status
+       )
+);
+
+#define DEFINE_CONN_EVENT(name)                                                \
+               DEFINE_EVENT(xprtrdma_connect_class, xprtrdma_##name,   \
+                               TP_PROTO(                               \
+                                       const struct rpcrdma_xprt *r_xprt, \
+                                       int rc                          \
+                               ),                                      \
+                               TP_ARGS(r_xprt, rc))
+
 DECLARE_EVENT_CLASS(xprtrdma_rdch_event,
        TP_PROTO(
                const struct rpc_task *task,
@@ -333,47 +371,81 @@ TRACE_EVENT(xprtrdma_cm_event,
        )
 );
 
-TRACE_EVENT(xprtrdma_disconnect,
+TRACE_EVENT(xprtrdma_inline_thresh,
        TP_PROTO(
-               const struct rpcrdma_xprt *r_xprt,
-               int status
+               const struct rpcrdma_xprt *r_xprt
        ),
 
-       TP_ARGS(r_xprt, status),
+       TP_ARGS(r_xprt),
 
        TP_STRUCT__entry(
                __field(const void *, r_xprt)
-               __field(int, status)
-               __field(int, connected)
+               __field(unsigned int, inline_send)
+               __field(unsigned int, inline_recv)
+               __field(unsigned int, max_send)
+               __field(unsigned int, max_recv)
                __string(addr, rpcrdma_addrstr(r_xprt))
                __string(port, rpcrdma_portstr(r_xprt))
        ),
 
        TP_fast_assign(
+               const struct rpcrdma_ep *ep = &r_xprt->rx_ep;
+
                __entry->r_xprt = r_xprt;
-               __entry->status = status;
-               __entry->connected = r_xprt->rx_ep.rep_connected;
+               __entry->inline_send = ep->rep_inline_send;
+               __entry->inline_recv = ep->rep_inline_recv;
+               __entry->max_send = ep->rep_max_inline_send;
+               __entry->max_recv = ep->rep_max_inline_recv;
                __assign_str(addr, rpcrdma_addrstr(r_xprt));
                __assign_str(port, rpcrdma_portstr(r_xprt));
        ),
 
-       TP_printk("peer=[%s]:%s r_xprt=%p: status=%d %sconnected",
-               __get_str(addr), __get_str(port),
-               __entry->r_xprt, __entry->status,
-               __entry->connected == 1 ? "still " : "dis"
+       TP_printk("peer=[%s]:%s r_xprt=%p neg send/recv=%u/%u, calc send/recv=%u/%u",
+               __get_str(addr), __get_str(port), __entry->r_xprt,
+               __entry->inline_send, __entry->inline_recv,
+               __entry->max_send, __entry->max_recv
        )
 );
 
-DEFINE_RXPRT_EVENT(xprtrdma_conn_start);
-DEFINE_RXPRT_EVENT(xprtrdma_conn_tout);
+DEFINE_CONN_EVENT(connect);
+DEFINE_CONN_EVENT(disconnect);
+
 DEFINE_RXPRT_EVENT(xprtrdma_create);
 DEFINE_RXPRT_EVENT(xprtrdma_op_destroy);
 DEFINE_RXPRT_EVENT(xprtrdma_remove);
 DEFINE_RXPRT_EVENT(xprtrdma_reinsert);
-DEFINE_RXPRT_EVENT(xprtrdma_reconnect);
 DEFINE_RXPRT_EVENT(xprtrdma_op_inject_dsc);
 DEFINE_RXPRT_EVENT(xprtrdma_op_close);
-DEFINE_RXPRT_EVENT(xprtrdma_op_connect);
+DEFINE_RXPRT_EVENT(xprtrdma_op_setport);
+
+TRACE_EVENT(xprtrdma_op_connect,
+       TP_PROTO(
+               const struct rpcrdma_xprt *r_xprt,
+               unsigned long delay
+       ),
+
+       TP_ARGS(r_xprt, delay),
+
+       TP_STRUCT__entry(
+               __field(const void *, r_xprt)
+               __field(unsigned long, delay)
+               __string(addr, rpcrdma_addrstr(r_xprt))
+               __string(port, rpcrdma_portstr(r_xprt))
+       ),
+
+       TP_fast_assign(
+               __entry->r_xprt = r_xprt;
+               __entry->delay = delay;
+               __assign_str(addr, rpcrdma_addrstr(r_xprt));
+               __assign_str(port, rpcrdma_portstr(r_xprt));
+       ),
+
+       TP_printk("peer=[%s]:%s r_xprt=%p delay=%lu",
+               __get_str(addr), __get_str(port), __entry->r_xprt,
+               __entry->delay
+       )
+);
+
 
 TRACE_EVENT(xprtrdma_op_set_cto,
        TP_PROTO(
@@ -532,6 +604,8 @@ DEFINE_WRCH_EVENT(write);
 DEFINE_WRCH_EVENT(reply);
 
 TRACE_DEFINE_ENUM(rpcrdma_noch);
+TRACE_DEFINE_ENUM(rpcrdma_noch_pullup);
+TRACE_DEFINE_ENUM(rpcrdma_noch_mapped);
 TRACE_DEFINE_ENUM(rpcrdma_readch);
 TRACE_DEFINE_ENUM(rpcrdma_areadch);
 TRACE_DEFINE_ENUM(rpcrdma_writech);
@@ -540,6 +614,8 @@ TRACE_DEFINE_ENUM(rpcrdma_replych);
 #define xprtrdma_show_chunktype(x)                                     \
                __print_symbolic(x,                                     \
                                { rpcrdma_noch, "inline" },             \
+                               { rpcrdma_noch_pullup, "pullup" },      \
+                               { rpcrdma_noch_mapped, "mapped" },      \
                                { rpcrdma_readch, "read list" },        \
                                { rpcrdma_areadch, "*read list" },      \
                                { rpcrdma_writech, "write list" },      \
@@ -667,9 +743,8 @@ TRACE_EVENT(xprtrdma_post_send,
                __entry->client_id = rqst->rq_task->tk_client ?
                                     rqst->rq_task->tk_client->cl_clid : -1;
                __entry->req = req;
-               __entry->num_sge = req->rl_sendctx->sc_wr.num_sge;
-               __entry->signaled = req->rl_sendctx->sc_wr.send_flags &
-                                   IB_SEND_SIGNALED;
+               __entry->num_sge = req->rl_wr.num_sge;
+               __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED;
                __entry->status = status;
        ),
 
@@ -735,6 +810,31 @@ TRACE_EVENT(xprtrdma_post_recvs,
        )
 );
 
+TRACE_EVENT(xprtrdma_post_linv,
+       TP_PROTO(
+               const struct rpcrdma_req *req,
+               int status
+       ),
+
+       TP_ARGS(req, status),
+
+       TP_STRUCT__entry(
+               __field(const void *, req)
+               __field(int, status)
+               __field(u32, xid)
+       ),
+
+       TP_fast_assign(
+               __entry->req = req;
+               __entry->status = status;
+               __entry->xid = be32_to_cpu(req->rl_slot.rq_xid);
+       ),
+
+       TP_printk("req=%p xid=0x%08x status=%d",
+               __entry->req, __entry->xid, __entry->status
+       )
+);
+
 /**
  ** Completion events
  **/
@@ -1021,66 +1121,32 @@ DEFINE_REPLY_EVENT(xprtrdma_reply_hdr);
 TRACE_EVENT(xprtrdma_fixup,
        TP_PROTO(
                const struct rpc_rqst *rqst,
-               int len,
-               int hdrlen
+               unsigned long fixup
        ),
 
-       TP_ARGS(rqst, len, hdrlen),
+       TP_ARGS(rqst, fixup),
 
        TP_STRUCT__entry(
                __field(unsigned int, task_id)
                __field(unsigned int, client_id)
-               __field(const void *, base)
-               __field(int, len)
-               __field(int, hdrlen)
-       ),
-
-       TP_fast_assign(
-               __entry->task_id = rqst->rq_task->tk_pid;
-               __entry->client_id = rqst->rq_task->tk_client->cl_clid;
-               __entry->base = rqst->rq_rcv_buf.head[0].iov_base;
-               __entry->len = len;
-               __entry->hdrlen = hdrlen;
-       ),
-
-       TP_printk("task:%u@%u base=%p len=%d hdrlen=%d",
-               __entry->task_id, __entry->client_id,
-               __entry->base, __entry->len, __entry->hdrlen
-       )
-);
-
-TRACE_EVENT(xprtrdma_fixup_pg,
-       TP_PROTO(
-               const struct rpc_rqst *rqst,
-               int pageno,
-               const void *pos,
-               int len,
-               int curlen
-       ),
-
-       TP_ARGS(rqst, pageno, pos, len, curlen),
-
-       TP_STRUCT__entry(
-               __field(unsigned int, task_id)
-               __field(unsigned int, client_id)
-               __field(const void *, pos)
-               __field(int, pageno)
-               __field(int, len)
-               __field(int, curlen)
+               __field(unsigned long, fixup)
+               __field(size_t, headlen)
+               __field(unsigned int, pagelen)
+               __field(size_t, taillen)
        ),
 
        TP_fast_assign(
                __entry->task_id = rqst->rq_task->tk_pid;
                __entry->client_id = rqst->rq_task->tk_client->cl_clid;
-               __entry->pos = pos;
-               __entry->pageno = pageno;
-               __entry->len = len;
-               __entry->curlen = curlen;
+               __entry->fixup = fixup;
+               __entry->headlen = rqst->rq_rcv_buf.head[0].iov_len;
+               __entry->pagelen = rqst->rq_rcv_buf.page_len;
+               __entry->taillen = rqst->rq_rcv_buf.tail[0].iov_len;
        ),
 
-       TP_printk("task:%u@%u pageno=%d pos=%p len=%d curlen=%d",
-               __entry->task_id, __entry->client_id,
-               __entry->pageno, __entry->pos, __entry->len, __entry->curlen
+       TP_printk("task:%u@%u fixup=%lu xdr=%zu/%u/%zu",
+               __entry->task_id, __entry->client_id, __entry->fixup,
+               __entry->headlen, __entry->pagelen, __entry->taillen
        )
 );
 
@@ -1498,31 +1564,47 @@ DEFINE_ERROR_EVENT(chunk);
  ** Server-side RDMA API events
  **/
 
-TRACE_EVENT(svcrdma_dma_map_page,
+DECLARE_EVENT_CLASS(svcrdma_dma_map_class,
        TP_PROTO(
                const struct svcxprt_rdma *rdma,
-               const void *page
+               u64 dma_addr,
+               u32 length
        ),
 
-       TP_ARGS(rdma, page),
+       TP_ARGS(rdma, dma_addr, length),
 
        TP_STRUCT__entry(
-               __field(const void *, page);
+               __field(u64, dma_addr)
+               __field(u32, length)
                __string(device, rdma->sc_cm_id->device->name)
                __string(addr, rdma->sc_xprt.xpt_remotebuf)
        ),
 
        TP_fast_assign(
-               __entry->page = page;
+               __entry->dma_addr = dma_addr;
+               __entry->length = length;
                __assign_str(device, rdma->sc_cm_id->device->name);
                __assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
        ),
 
-       TP_printk("addr=%s device=%s page=%p",
-               __get_str(addr), __get_str(device), __entry->page
+       TP_printk("addr=%s device=%s dma_addr=%llu length=%u",
+               __get_str(addr), __get_str(device),
+               __entry->dma_addr, __entry->length
        )
 );
 
+#define DEFINE_SVC_DMA_EVENT(name)                                     \
+               DEFINE_EVENT(svcrdma_dma_map_class, svcrdma_##name,     \
+                               TP_PROTO(                               \
+                                       const struct svcxprt_rdma *rdma,\
+                                       u64 dma_addr,                   \
+                                       u32 length                      \
+                               ),                                      \
+                               TP_ARGS(rdma, dma_addr, length))
+
+DEFINE_SVC_DMA_EVENT(dma_map_page);
+DEFINE_SVC_DMA_EVENT(dma_unmap_page);
+
 TRACE_EVENT(svcrdma_dma_map_rwctx,
        TP_PROTO(
                const struct svcxprt_rdma *rdma,
index ffa3c51..8c73ffb 100644 (file)
 #include <linux/net.h>
 #include <linux/tracepoint.h>
 
+TRACE_DEFINE_ENUM(RPC_AUTH_OK);
+TRACE_DEFINE_ENUM(RPC_AUTH_BADCRED);
+TRACE_DEFINE_ENUM(RPC_AUTH_REJECTEDCRED);
+TRACE_DEFINE_ENUM(RPC_AUTH_BADVERF);
+TRACE_DEFINE_ENUM(RPC_AUTH_REJECTEDVERF);
+TRACE_DEFINE_ENUM(RPC_AUTH_TOOWEAK);
+TRACE_DEFINE_ENUM(RPCSEC_GSS_CREDPROBLEM);
+TRACE_DEFINE_ENUM(RPCSEC_GSS_CTXPROBLEM);
+
+#define rpc_show_auth_stat(status)                                     \
+       __print_symbolic(status,                                        \
+               { RPC_AUTH_OK,                  "AUTH_OK" },            \
+               { RPC_AUTH_BADCRED,             "BADCRED" },            \
+               { RPC_AUTH_REJECTEDCRED,        "REJECTEDCRED" },       \
+               { RPC_AUTH_BADVERF,             "BADVERF" },            \
+               { RPC_AUTH_REJECTEDVERF,        "REJECTEDVERF" },       \
+               { RPC_AUTH_TOOWEAK,             "TOOWEAK" },            \
+               { RPCSEC_GSS_CREDPROBLEM,       "GSS_CREDPROBLEM" },    \
+               { RPCSEC_GSS_CTXPROBLEM,        "GSS_CTXPROBLEM" })     \
+
 DECLARE_EVENT_CLASS(rpc_task_status,
 
        TP_PROTO(const struct rpc_task *task),
@@ -165,6 +185,7 @@ DECLARE_EVENT_CLASS(rpc_task_running,
 DEFINE_RPC_RUNNING_EVENT(begin);
 DEFINE_RPC_RUNNING_EVENT(run_action);
 DEFINE_RPC_RUNNING_EVENT(complete);
+DEFINE_RPC_RUNNING_EVENT(end);
 
 DECLARE_EVENT_CLASS(rpc_task_queued,
 
@@ -777,6 +798,99 @@ TRACE_EVENT(xprt_ping,
                        __get_str(addr), __get_str(port), __entry->status)
 );
 
+DECLARE_EVENT_CLASS(xprt_writelock_event,
+       TP_PROTO(
+               const struct rpc_xprt *xprt, const struct rpc_task *task
+       ),
+
+       TP_ARGS(xprt, task),
+
+       TP_STRUCT__entry(
+               __field(unsigned int, task_id)
+               __field(unsigned int, client_id)
+               __field(unsigned int, snd_task_id)
+       ),
+
+       TP_fast_assign(
+               if (task) {
+                       __entry->task_id = task->tk_pid;
+                       __entry->client_id = task->tk_client ?
+                                            task->tk_client->cl_clid : -1;
+               } else {
+                       __entry->task_id = -1;
+                       __entry->client_id = -1;
+               }
+               __entry->snd_task_id = xprt->snd_task ?
+                                       xprt->snd_task->tk_pid : -1;
+       ),
+
+       TP_printk("task:%u@%u snd_task:%u",
+                       __entry->task_id, __entry->client_id,
+                       __entry->snd_task_id)
+);
+
+#define DEFINE_WRITELOCK_EVENT(name) \
+       DEFINE_EVENT(xprt_writelock_event, xprt_##name, \
+                       TP_PROTO( \
+                               const struct rpc_xprt *xprt, \
+                               const struct rpc_task *task \
+                       ), \
+                       TP_ARGS(xprt, task))
+
+DEFINE_WRITELOCK_EVENT(reserve_xprt);
+DEFINE_WRITELOCK_EVENT(release_xprt);
+
+DECLARE_EVENT_CLASS(xprt_cong_event,
+       TP_PROTO(
+               const struct rpc_xprt *xprt, const struct rpc_task *task
+       ),
+
+       TP_ARGS(xprt, task),
+
+       TP_STRUCT__entry(
+               __field(unsigned int, task_id)
+               __field(unsigned int, client_id)
+               __field(unsigned int, snd_task_id)
+               __field(unsigned long, cong)
+               __field(unsigned long, cwnd)
+               __field(bool, wait)
+       ),
+
+       TP_fast_assign(
+               if (task) {
+                       __entry->task_id = task->tk_pid;
+                       __entry->client_id = task->tk_client ?
+                                            task->tk_client->cl_clid : -1;
+               } else {
+                       __entry->task_id = -1;
+                       __entry->client_id = -1;
+               }
+               __entry->snd_task_id = xprt->snd_task ?
+                                       xprt->snd_task->tk_pid : -1;
+               __entry->cong = xprt->cong;
+               __entry->cwnd = xprt->cwnd;
+               __entry->wait = test_bit(XPRT_CWND_WAIT, &xprt->state);
+       ),
+
+       TP_printk("task:%u@%u snd_task:%u cong=%lu cwnd=%lu%s",
+                       __entry->task_id, __entry->client_id,
+                       __entry->snd_task_id, __entry->cong, __entry->cwnd,
+                       __entry->wait ? " (wait)" : "")
+);
+
+#define DEFINE_CONG_EVENT(name) \
+       DEFINE_EVENT(xprt_cong_event, xprt_##name, \
+                       TP_PROTO( \
+                               const struct rpc_xprt *xprt, \
+                               const struct rpc_task *task \
+                       ), \
+                       TP_ARGS(xprt, task))
+
+DEFINE_CONG_EVENT(reserve_cong);
+DEFINE_CONG_EVENT(release_cong);
+DEFINE_CONG_EVENT(get_cong);
+DEFINE_CONG_EVENT(put_cong);
+
 TRACE_EVENT(xs_stream_read_data,
        TP_PROTO(struct rpc_xprt *xprt, ssize_t err, size_t total),
 
@@ -866,6 +980,41 @@ TRACE_EVENT(svc_recv,
                        show_rqstp_flags(__entry->flags))
 );
 
+#define svc_show_status(status)                                \
+       __print_symbolic(status,                        \
+               { SVC_GARBAGE,  "SVC_GARBAGE" },        \
+               { SVC_SYSERR,   "SVC_SYSERR" },         \
+               { SVC_VALID,    "SVC_VALID" },          \
+               { SVC_NEGATIVE, "SVC_NEGATIVE" },       \
+               { SVC_OK,       "SVC_OK" },             \
+               { SVC_DROP,     "SVC_DROP" },           \
+               { SVC_CLOSE,    "SVC_CLOSE" },          \
+               { SVC_DENIED,   "SVC_DENIED" },         \
+               { SVC_PENDING,  "SVC_PENDING" },        \
+               { SVC_COMPLETE, "SVC_COMPLETE" })
+
+TRACE_EVENT(svc_authenticate,
+       TP_PROTO(const struct svc_rqst *rqst, int auth_res, __be32 auth_stat),
+
+       TP_ARGS(rqst, auth_res, auth_stat),
+
+       TP_STRUCT__entry(
+               __field(u32, xid)
+               __field(unsigned long, svc_status)
+               __field(unsigned long, auth_stat)
+       ),
+
+       TP_fast_assign(
+               __entry->xid = be32_to_cpu(rqst->rq_xid);
+               __entry->svc_status = auth_res;
+               __entry->auth_stat = be32_to_cpu(auth_stat);
+       ),
+
+       TP_printk("xid=0x%08x auth_res=%s auth_stat=%s",
+                       __entry->xid, svc_show_status(__entry->svc_status),
+                       rpc_show_auth_stat(__entry->auth_stat))
+);
+
 TRACE_EVENT(svc_process,
        TP_PROTO(const struct svc_rqst *rqst, const char *name),
 
index 7089760..472b33d 100644 (file)
@@ -757,6 +757,7 @@ static inline void ftrace_test_probe_##call(void)                   \
 #undef __get_str
 #undef __get_bitmask
 #undef __print_array
+#undef __print_hex_dump
 
 #undef TP_printk
 #define TP_printk(fmt, args...) "\"" fmt "\", "  __stringify(args)
index 7d80dbd..41a01b4 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef __ASM_GENERIC_IPCBUF_H
 #define __ASM_GENERIC_IPCBUF_H
 
+#include <linux/posix_types.h>
+
 /*
  * The generic ipc64_perm structure:
  * Note extra padding because this structure is passed back and forth
index af95aa8..6504d7b 100644 (file)
@@ -3,6 +3,8 @@
 #define __ASM_GENERIC_MSGBUF_H
 
 #include <asm/bitsperlong.h>
+#include <asm/ipcbuf.h>
+
 /*
  * generic msqid64_ds structure.
  *
index 1376060..0e709bd 100644 (file)
@@ -3,6 +3,7 @@
 #define __ASM_GENERIC_SEMBUF_H
 
 #include <asm/bitsperlong.h>
+#include <asm/ipcbuf.h>
 
 /*
  * The semid64_ds structure for x86 architecture.
index 00aebea..0f1db1c 100644 (file)
  */
 #define KEY_DATA                       0x277
 #define KEY_ONSCREEN_KEYBOARD          0x278
+/* Electronic privacy screen control */
+#define KEY_PRIVACY_SCREEN_TOGGLE      0x279
 
 /*
  * Some keyboards have keys which do not have a defined meaning, these keys
index 4637ed1..a3300e1 100644 (file)
@@ -48,6 +48,7 @@ struct io_uring_sqe {
 #define IOSQE_FIXED_FILE       (1U << 0)       /* use fixed fileset */
 #define IOSQE_IO_DRAIN         (1U << 1)       /* issue after inflight IO */
 #define IOSQE_IO_LINK          (1U << 2)       /* links next sqe */
+#define IOSQE_IO_HARDLINK      (1U << 3)       /* like LINK, but stronger */
 
 /*
  * io_uring_setup() flags
@@ -57,23 +58,28 @@ struct io_uring_sqe {
 #define IORING_SETUP_SQ_AFF    (1U << 2)       /* sq_thread_cpu is valid */
 #define IORING_SETUP_CQSIZE    (1U << 3)       /* app defines CQ size */
 
-#define IORING_OP_NOP          0
-#define IORING_OP_READV                1
-#define IORING_OP_WRITEV       2
-#define IORING_OP_FSYNC                3
-#define IORING_OP_READ_FIXED   4
-#define IORING_OP_WRITE_FIXED  5
-#define IORING_OP_POLL_ADD     6
-#define IORING_OP_POLL_REMOVE  7
-#define IORING_OP_SYNC_FILE_RANGE      8
-#define IORING_OP_SENDMSG      9
-#define IORING_OP_RECVMSG      10
-#define IORING_OP_TIMEOUT      11
-#define IORING_OP_TIMEOUT_REMOVE       12
-#define IORING_OP_ACCEPT       13
-#define IORING_OP_ASYNC_CANCEL 14
-#define IORING_OP_LINK_TIMEOUT 15
-#define IORING_OP_CONNECT      16
+enum {
+       IORING_OP_NOP,
+       IORING_OP_READV,
+       IORING_OP_WRITEV,
+       IORING_OP_FSYNC,
+       IORING_OP_READ_FIXED,
+       IORING_OP_WRITE_FIXED,
+       IORING_OP_POLL_ADD,
+       IORING_OP_POLL_REMOVE,
+       IORING_OP_SYNC_FILE_RANGE,
+       IORING_OP_SENDMSG,
+       IORING_OP_RECVMSG,
+       IORING_OP_TIMEOUT,
+       IORING_OP_TIMEOUT_REMOVE,
+       IORING_OP_ACCEPT,
+       IORING_OP_ASYNC_CANCEL,
+       IORING_OP_LINK_TIMEOUT,
+       IORING_OP_CONNECT,
+
+       /* this goes last, obviously */
+       IORING_OP_LAST,
+};
 
 /*
  * sqe->fsync_flags
@@ -157,6 +163,7 @@ struct io_uring_params {
  */
 #define IORING_FEAT_SINGLE_MMAP                (1U << 0)
 #define IORING_FEAT_NODROP             (1U << 1)
+#define IORING_FEAT_SUBMIT_STABLE      (1U << 2)
 
 /*
  * io_uring_register(2) opcodes and arguments
index 9529867..409d3ad 100644 (file)
@@ -4,9 +4,24 @@
 
 #include <linux/types.h>
 
+/*
+ * Argument for KCOV_REMOTE_ENABLE ioctl, see Documentation/dev-tools/kcov.rst
+ * and the comment before kcov_remote_start() for usage details.
+ */
+struct kcov_remote_arg {
+       unsigned int    trace_mode;     /* KCOV_TRACE_PC or KCOV_TRACE_CMP */
+       unsigned int    area_size;      /* Length of coverage buffer in words */
+       unsigned int    num_handles;    /* Size of handles array */
+       __u64           common_handle;
+       __u64           handles[0];
+};
+
+#define KCOV_REMOTE_MAX_HANDLES                0x100
+
 #define KCOV_INIT_TRACE                        _IOR('c', 1, unsigned long)
 #define KCOV_ENABLE                    _IO('c', 100)
 #define KCOV_DISABLE                   _IO('c', 101)
+#define KCOV_REMOTE_ENABLE             _IOW('c', 102, struct kcov_remote_arg)
 
 enum {
        /*
@@ -32,4 +47,17 @@ enum {
 #define KCOV_CMP_SIZE(n)        ((n) << 1)
 #define KCOV_CMP_MASK           KCOV_CMP_SIZE(3)
 
+#define KCOV_SUBSYSTEM_COMMON  (0x00ull << 56)
+#define KCOV_SUBSYSTEM_USB     (0x01ull << 56)
+
+#define KCOV_SUBSYSTEM_MASK    (0xffull << 56)
+#define KCOV_INSTANCE_MASK     (0xffffffffull)
+
+static inline __u64 kcov_remote_handle(__u64 subsys, __u64 inst)
+{
+       if (subsys & ~KCOV_SUBSYSTEM_MASK || inst & ~KCOV_INSTANCE_MASK)
+               return 0;
+       return subsys | inst;
+}
+
 #endif /* _LINUX_KCOV_IOCTLS_H */
index e6f17c8..f0a16b4 100644 (file)
@@ -1348,6 +1348,7 @@ struct kvm_s390_ucas_mapping {
 #define KVM_PPC_GET_CPU_CHAR     _IOR(KVMIO,  0xb1, struct kvm_ppc_cpu_char)
 /* Available with KVM_CAP_PMU_EVENT_FILTER */
 #define KVM_SET_PMU_EVENT_FILTER  _IOW(KVMIO,  0xb2, struct kvm_pmu_event_filter)
+#define KVM_PPC_SVM_OFF                  _IO(KVMIO,  0xb3)
 
 /* ioctl for vm fd */
 #define KVM_CREATE_DEVICE        _IOWR(KVMIO,  0xe0, struct kvm_create_device)
index c5bc7f7..947edb1 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef _UAPI_SCC_H
 #define _UAPI_SCC_H
 
+#include <linux/sockios.h>
 
 /* selection of hardware types */
 
index d7163fc..a34064a 100644 (file)
@@ -146,13 +146,13 @@ config LOCALVERSION_AUTO
          which is done within the script "scripts/setlocalversion".)
 
 config BUILD_SALT
-       string "Build ID Salt"
-       default ""
-       help
-          The build ID is used to link binaries and their debug info. Setting
-          this option will use the value in the calculation of the build id.
-          This is mostly useful for distributions which want to ensure the
-          build is unique between builds. It's safe to leave the default.
+       string "Build ID Salt"
+       default ""
+       help
+         The build ID is used to link binaries and their debug info. Setting
+         this option will use the value in the calculation of the build id.
+         This is mostly useful for distributions which want to ensure the
+         build is unique between builds. It's safe to leave the default.
 
 config HAVE_KERNEL_GZIP
        bool
@@ -818,7 +818,7 @@ menuconfig CGROUPS
 if CGROUPS
 
 config PAGE_COUNTER
-       bool
+       bool
 
 config MEMCG
        bool "Memory controller"
@@ -1311,9 +1311,9 @@ menuconfig EXPERT
        select DEBUG_KERNEL
        help
          This option allows certain base kernel options and settings
-          to be disabled or tweaked. This is for specialized
-          environments which can tolerate a "non-standard" kernel.
-          Only use this if you really know what you are doing.
+         to be disabled or tweaked. This is for specialized
+         environments which can tolerate a "non-standard" kernel.
+         Only use this if you really know what you are doing.
 
 config UID16
        bool "Enable 16-bit UID system calls" if EXPERT
@@ -1406,11 +1406,11 @@ config BUG
        bool "BUG() support" if EXPERT
        default y
        help
-          Disabling this option eliminates support for BUG and WARN, reducing
-          the size of your kernel image and potentially quietly ignoring
-          numerous fatal conditions. You should only consider disabling this
-          option for embedded systems with no facilities for reporting errors.
-          Just say Y.
+         Disabling this option eliminates support for BUG and WARN, reducing
+         the size of your kernel image and potentially quietly ignoring
+         numerous fatal conditions. You should only consider disabling this
+         option for embedded systems with no facilities for reporting errors.
+         Just say Y.
 
 config ELF_CORE
        depends on COREDUMP
@@ -1426,8 +1426,8 @@ config PCSPKR_PLATFORM
        select I8253_LOCK
        default y
        help
-          This option allows to disable the internal PC-Speaker
-          support, saving some memory.
+         This option allows to disable the internal PC-Speaker
+         support, saving some memory.
 
 config BASE_FULL
        default y
@@ -1545,29 +1545,29 @@ config MEMBARRIER
          If unsure, say Y.
 
 config KALLSYMS
-        bool "Load all symbols for debugging/ksymoops" if EXPERT
-        default y
-        help
-          Say Y here to let the kernel print out symbolic crash information and
-          symbolic stack backtraces. This increases the size of the kernel
-          somewhat, as all symbols have to be loaded into the kernel image.
+       bool "Load all symbols for debugging/ksymoops" if EXPERT
+       default y
+       help
+         Say Y here to let the kernel print out symbolic crash information and
+         symbolic stack backtraces. This increases the size of the kernel
+         somewhat, as all symbols have to be loaded into the kernel image.
 
 config KALLSYMS_ALL
        bool "Include all symbols in kallsyms"
        depends on DEBUG_KERNEL && KALLSYMS
        help
-          Normally kallsyms only contains the symbols of functions for nicer
-          OOPS messages and backtraces (i.e., symbols from the text and inittext
-          sections). This is sufficient for most cases. And only in very rare
-          cases (e.g., when a debugger is used) all symbols are required (e.g.,
-          names of variables from the data sections, etc).
+         Normally kallsyms only contains the symbols of functions for nicer
+         OOPS messages and backtraces (i.e., symbols from the text and inittext
+         sections). This is sufficient for most cases. And only in very rare
+         cases (e.g., when a debugger is used) all symbols are required (e.g.,
+         names of variables from the data sections, etc).
 
-          This option makes sure that all symbols are loaded into the kernel
-          image (i.e., symbols from all sections) in cost of increased kernel
-          size (depending on the kernel configuration, it may be 300KiB or
-          something like this).
+         This option makes sure that all symbols are loaded into the kernel
+         image (i.e., symbols from all sections) in cost of increased kernel
+         size (depending on the kernel configuration, it may be 300KiB or
+         something like this).
 
-          Say N unless you really need all symbols.
+         Say N unless you really need all symbols.
 
 config KALLSYMS_ABSOLUTE_PERCPU
        bool
@@ -1710,12 +1710,12 @@ config DEBUG_PERF_USE_VMALLOC
        depends on PERF_EVENTS && DEBUG_KERNEL && !PPC
        select PERF_USE_VMALLOC
        help
-        Use vmalloc memory to back perf mmap() buffers.
+         Use vmalloc memory to back perf mmap() buffers.
 
-        Mostly useful for debugging the vmalloc code on platforms
-        that don't require it.
+         Mostly useful for debugging the vmalloc code on platforms
+         that don't require it.
 
-        Say N if unsure.
+         Say N if unsure.
 
 endmenu
 
index af9cda8..0ae9cc2 100644 (file)
@@ -387,12 +387,27 @@ static void __init get_fs_names(char *page)
        *s = '\0';
 }
 
-static int __init do_mount_root(char *name, char *fs, int flags, void *data)
+static int __init do_mount_root(const char *name, const char *fs,
+                                const int flags, const void *data)
 {
        struct super_block *s;
-       int err = ksys_mount(name, "/root", fs, flags, data);
-       if (err)
-               return err;
+       struct page *p = NULL;
+       char *data_page = NULL;
+       int ret;
+
+       if (data) {
+               /* do_mount() requires a full page as fifth argument */
+               p = alloc_page(GFP_KERNEL);
+               if (!p)
+                       return -ENOMEM;
+               data_page = page_address(p);
+               /* zero-pad. do_mount() will make sure it's terminated */
+               strncpy(data_page, data, PAGE_SIZE);
+       }
+
+       ret = do_mount(name, "/root", fs, flags, data_page);
+       if (ret)
+               goto out;
 
        ksys_chdir("/root");
        s = current->fs->pwd.dentry->d_sb;
@@ -402,7 +417,11 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data)
               s->s_type->name,
               sb_rdonly(s) ? " readonly" : "",
               MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
-       return 0;
+
+out:
+       if (p)
+               put_page(p);
+       return ret;
 }
 
 void __init mount_block_root(char *name, int flags)
@@ -670,8 +689,8 @@ void __init prepare_namespace(void)
 
        mount_root();
 out:
-       devtmpfs_mount("dev");
-       ksys_mount(".", "/", NULL, MS_MOVE, NULL);
+       devtmpfs_mount();
+       do_mount(".", "/", NULL, MS_MOVE, NULL);
        ksys_chroot(".");
 }
 
index a9c6cc5..dab8b11 100644 (file)
@@ -48,13 +48,10 @@ early_param("initrd", early_initrd);
 static int init_linuxrc(struct subprocess_info *info, struct cred *new)
 {
        ksys_unshare(CLONE_FS | CLONE_FILES);
-       /* stdin/stdout/stderr for /linuxrc */
-       ksys_open("/dev/console", O_RDWR, 0);
-       ksys_dup(0);
-       ksys_dup(0);
+       console_on_rootfs();
        /* move initrd over / and chdir/chroot in initrd root */
        ksys_chdir("/root");
-       ksys_mount(".", "/", NULL, MS_MOVE, NULL);
+       do_mount(".", "/", NULL, MS_MOVE, NULL);
        ksys_chroot(".");
        ksys_setsid();
        return 0;
@@ -89,7 +86,7 @@ static void __init handle_initrd(void)
        current->flags &= ~PF_FREEZER_SKIP;
 
        /* move initrd to rootfs' /old */
-       ksys_mount("..", ".", NULL, MS_MOVE, NULL);
+       do_mount("..", ".", NULL, MS_MOVE, NULL);
        /* switch root and cwd back to / of rootfs */
        ksys_chroot("..");
 
@@ -103,7 +100,7 @@ static void __init handle_initrd(void)
        mount_root();
 
        printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
-       error = ksys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+       error = do_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
        if (!error)
                printk("okay\n");
        else {
index 91f6ebb..ec3a146 100644 (file)
@@ -93,6 +93,7 @@
 #include <linux/rodata_test.h>
 #include <linux/jump_label.h>
 #include <linux/mem_encrypt.h>
+#include <linux/file.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -1155,6 +1156,30 @@ static int __ref kernel_init(void *unused)
              "See Linux Documentation/admin-guide/init.rst for guidance.");
 }
 
+void console_on_rootfs(void)
+{
+       struct file *file;
+       unsigned int i;
+
+       /* Open /dev/console in kernelspace, this should never fail */
+       file = filp_open("/dev/console", O_RDWR, 0);
+       if (!file)
+               goto err_out;
+
+       /* create stdin/stdout/stderr, this should never fail */
+       for (i = 0; i < 3; i++) {
+               if (f_dupfd(i, file, 0) != i)
+                       goto err_out;
+       }
+
+       return;
+
+err_out:
+       /* no panic -- this might not be fatal */
+       pr_err("Warning: unable to open an initial console.\n");
+       return;
+}
+
 static noinline void __init kernel_init_freeable(void)
 {
        /*
@@ -1190,12 +1215,8 @@ static noinline void __init kernel_init_freeable(void)
 
        do_basic_setup();
 
-       /* Open the /dev/console on the rootfs, this should never fail */
-       if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
-               pr_err("Warning: unable to open an initial console.\n");
+       console_on_rootfs();
 
-       (void) ksys_dup(0);
-       (void) ksys_dup(0);
        /*
         * check if there is an early userspace init.  If yes, let it do all
         * the work
index d126d15..915eacb 100644 (file)
@@ -100,7 +100,7 @@ device_initcall(ipc_init);
 static const struct rhashtable_params ipc_kht_params = {
        .head_offset            = offsetof(struct kern_ipc_perm, khtnode),
        .key_offset             = offsetof(struct kern_ipc_perm, key),
-       .key_len                = FIELD_SIZEOF(struct kern_ipc_perm, key),
+       .key_len                = sizeof_field(struct kern_ipc_perm, key),
        .automatic_shrinking    = true,
 };
 
index 40efde5..7d40da2 100644 (file)
@@ -3463,6 +3463,7 @@ enum {
        __ctx_convert##_id,
 #include <linux/bpf_types.h>
 #undef BPF_PROG_TYPE
+       __ctx_convert_unused, /* to avoid empty enum in extreme .config */
 };
 static u8 bpf_ctx_convert_map[] = {
 #define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \
@@ -3976,8 +3977,10 @@ static int __get_type_size(struct btf *btf, u32 btf_id,
        t = btf_type_by_id(btf, btf_id);
        while (t && btf_type_is_modifier(t))
                t = btf_type_by_id(btf, t->type);
-       if (!t)
+       if (!t) {
+               *bad_type = btf->types[0];
                return -EINVAL;
+       }
        if (btf_type_is_ptr(t))
                /* kernel size of pointer. Not BPF's size of pointer*/
                return sizeof(void *);
index 9f90d3c..4fb20ab 100644 (file)
@@ -1341,7 +1341,7 @@ static u32 sysctl_convert_ctx_access(enum bpf_access_type type,
                *insn++ = BPF_LDX_MEM(
                        BPF_SIZE(si->code), si->dst_reg, si->src_reg,
                        bpf_target_off(struct bpf_sysctl_kern, write,
-                                      FIELD_SIZEOF(struct bpf_sysctl_kern,
+                                      sizeof_field(struct bpf_sysctl_kern,
                                                    write),
                                       target_size));
                break;
index 2ba7507..6bd22f6 100644 (file)
@@ -357,7 +357,7 @@ static int cgroup_storage_check_btf(const struct bpf_map *map,
         * The first field must be a 64 bit integer at 0 offset.
         */
        m = (struct btf_member *)(key_type + 1);
-       size = FIELD_SIZEOF(struct bpf_cgroup_storage_key, cgroup_inode_id);
+       size = sizeof_field(struct bpf_cgroup_storage_key, cgroup_inode_id);
        if (!btf_member_is_reg_int(btf, key_type, m, 0, size))
                return -EINVAL;
 
@@ -366,7 +366,7 @@ static int cgroup_storage_check_btf(const struct bpf_map *map,
         */
        m++;
        offset = offsetof(struct bpf_cgroup_storage_key, attach_type);
-       size = FIELD_SIZEOF(struct bpf_cgroup_storage_key, attach_type);
+       size = sizeof_field(struct bpf_cgroup_storage_key, attach_type);
        if (!btf_member_is_reg_int(btf, key_type, m, offset, size))
                return -EINVAL;
 
index a0482e1..034ef81 100644 (file)
@@ -9636,7 +9636,10 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
                                ret = -EINVAL;
                                goto out;
                        }
-                       addr = (long) tgt_prog->aux->func[subprog]->bpf_func;
+                       if (subprog == 0)
+                               addr = (long) tgt_prog->bpf_func;
+                       else
+                               addr = (long) tgt_prog->aux->func[subprog]->bpf_func;
                } else {
                        addr = kallsyms_lookup_name(tname);
                        if (!addr) {
index d47bd40..d14cbc8 100644 (file)
@@ -178,7 +178,7 @@ bool dma_in_atomic_pool(void *start, size_t size)
        if (unlikely(!atomic_pool))
                return false;
 
-       return addr_in_gen_pool(atomic_pool, (unsigned long)start, size);
+       return gen_pool_has_addr(atomic_pool, (unsigned long)start, size);
 }
 
 void *dma_alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags)
index 2ee3872..f503542 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/hashtable.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/preempt.h>
 #include <linux/uaccess.h>
 #include <linux/kcov.h>
 #include <linux/refcount.h>
+#include <linux/log2.h>
 #include <asm/setup.h>
 
+#define kcov_debug(fmt, ...) pr_debug("%s: " fmt, __func__, ##__VA_ARGS__)
+
 /* Number of 64-bit words written per one comparison: */
 #define KCOV_WORDS_PER_CMP 4
 
@@ -44,19 +48,100 @@ struct kcov {
         * Reference counter. We keep one for:
         *  - opened file descriptor
         *  - task with enabled coverage (we can't unwire it from another task)
+        *  - each code section for remote coverage collection
         */
        refcount_t              refcount;
        /* The lock protects mode, size, area and t. */
        spinlock_t              lock;
        enum kcov_mode          mode;
-       /* Size of arena (in long's for KCOV_MODE_TRACE). */
-       unsigned                size;
+       /* Size of arena (in long's). */
+       unsigned int            size;
        /* Coverage buffer shared with user space. */
        void                    *area;
        /* Task for which we collect coverage, or NULL. */
        struct task_struct      *t;
+       /* Collecting coverage from remote (background) threads. */
+       bool                    remote;
+       /* Size of remote area (in long's). */
+       unsigned int            remote_size;
+       /*
+        * Sequence is incremented each time kcov is reenabled, used by
+        * kcov_remote_stop(), see the comment there.
+        */
+       int                     sequence;
 };
 
+struct kcov_remote_area {
+       struct list_head        list;
+       unsigned int            size;
+};
+
+struct kcov_remote {
+       u64                     handle;
+       struct kcov             *kcov;
+       struct hlist_node       hnode;
+};
+
+static DEFINE_SPINLOCK(kcov_remote_lock);
+static DEFINE_HASHTABLE(kcov_remote_map, 4);
+static struct list_head kcov_remote_areas = LIST_HEAD_INIT(kcov_remote_areas);
+
+/* Must be called with kcov_remote_lock locked. */
+static struct kcov_remote *kcov_remote_find(u64 handle)
+{
+       struct kcov_remote *remote;
+
+       hash_for_each_possible(kcov_remote_map, remote, hnode, handle) {
+               if (remote->handle == handle)
+                       return remote;
+       }
+       return NULL;
+}
+
+static struct kcov_remote *kcov_remote_add(struct kcov *kcov, u64 handle)
+{
+       struct kcov_remote *remote;
+
+       if (kcov_remote_find(handle))
+               return ERR_PTR(-EEXIST);
+       remote = kmalloc(sizeof(*remote), GFP_ATOMIC);
+       if (!remote)
+               return ERR_PTR(-ENOMEM);
+       remote->handle = handle;
+       remote->kcov = kcov;
+       hash_add(kcov_remote_map, &remote->hnode, handle);
+       return remote;
+}
+
+/* Must be called with kcov_remote_lock locked. */
+static struct kcov_remote_area *kcov_remote_area_get(unsigned int size)
+{
+       struct kcov_remote_area *area;
+       struct list_head *pos;
+
+       kcov_debug("size = %u\n", size);
+       list_for_each(pos, &kcov_remote_areas) {
+               area = list_entry(pos, struct kcov_remote_area, list);
+               if (area->size == size) {
+                       list_del(&area->list);
+                       kcov_debug("rv = %px\n", area);
+                       return area;
+               }
+       }
+       kcov_debug("rv = NULL\n");
+       return NULL;
+}
+
+/* Must be called with kcov_remote_lock locked. */
+static void kcov_remote_area_put(struct kcov_remote_area *area,
+                                       unsigned int size)
+{
+       kcov_debug("area = %px, size = %u\n", area, size);
+       INIT_LIST_HEAD(&area->list);
+       area->size = size;
+       list_add(&area->list, &kcov_remote_areas);
+}
+
 static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t)
 {
        unsigned int mode;
@@ -73,7 +158,7 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru
         * in_interrupt() returns false (e.g. preempt_schedule_irq()).
         * READ_ONCE()/barrier() effectively provides load-acquire wrt
         * interrupts, there are paired barrier()/WRITE_ONCE() in
-        * kcov_ioctl_locked().
+        * kcov_start().
         */
        barrier();
        return mode == needed_mode;
@@ -227,6 +312,78 @@ void notrace __sanitizer_cov_trace_switch(u64 val, u64 *cases)
 EXPORT_SYMBOL(__sanitizer_cov_trace_switch);
 #endif /* ifdef CONFIG_KCOV_ENABLE_COMPARISONS */
 
+static void kcov_start(struct task_struct *t, unsigned int size,
+                       void *area, enum kcov_mode mode, int sequence)
+{
+       kcov_debug("t = %px, size = %u, area = %px\n", t, size, area);
+       /* Cache in task struct for performance. */
+       t->kcov_size = size;
+       t->kcov_area = area;
+       /* See comment in check_kcov_mode(). */
+       barrier();
+       WRITE_ONCE(t->kcov_mode, mode);
+       t->kcov_sequence = sequence;
+}
+
+static void kcov_stop(struct task_struct *t)
+{
+       WRITE_ONCE(t->kcov_mode, KCOV_MODE_DISABLED);
+       barrier();
+       t->kcov_size = 0;
+       t->kcov_area = NULL;
+}
+
+static void kcov_task_reset(struct task_struct *t)
+{
+       kcov_stop(t);
+       t->kcov = NULL;
+       t->kcov_sequence = 0;
+       t->kcov_handle = 0;
+}
+
+void kcov_task_init(struct task_struct *t)
+{
+       kcov_task_reset(t);
+       t->kcov_handle = current->kcov_handle;
+}
+
+static void kcov_reset(struct kcov *kcov)
+{
+       kcov->t = NULL;
+       kcov->mode = KCOV_MODE_INIT;
+       kcov->remote = false;
+       kcov->remote_size = 0;
+       kcov->sequence++;
+}
+
+static void kcov_remote_reset(struct kcov *kcov)
+{
+       int bkt;
+       struct kcov_remote *remote;
+       struct hlist_node *tmp;
+
+       spin_lock(&kcov_remote_lock);
+       hash_for_each_safe(kcov_remote_map, bkt, tmp, remote, hnode) {
+               if (remote->kcov != kcov)
+                       continue;
+               kcov_debug("removing handle %llx\n", remote->handle);
+               hash_del(&remote->hnode);
+               kfree(remote);
+       }
+       /* Do reset before unlock to prevent races with kcov_remote_start(). */
+       kcov_reset(kcov);
+       spin_unlock(&kcov_remote_lock);
+}
+
+static void kcov_disable(struct task_struct *t, struct kcov *kcov)
+{
+       kcov_task_reset(t);
+       if (kcov->remote)
+               kcov_remote_reset(kcov);
+       else
+               kcov_reset(kcov);
+}
+
 static void kcov_get(struct kcov *kcov)
 {
        refcount_inc(&kcov->refcount);
@@ -235,20 +392,12 @@ static void kcov_get(struct kcov *kcov)
 static void kcov_put(struct kcov *kcov)
 {
        if (refcount_dec_and_test(&kcov->refcount)) {
+               kcov_remote_reset(kcov);
                vfree(kcov->area);
                kfree(kcov);
        }
 }
 
-void kcov_task_init(struct task_struct *t)
-{
-       WRITE_ONCE(t->kcov_mode, KCOV_MODE_DISABLED);
-       barrier();
-       t->kcov_size = 0;
-       t->kcov_area = NULL;
-       t->kcov = NULL;
-}
-
 void kcov_task_exit(struct task_struct *t)
 {
        struct kcov *kcov;
@@ -256,15 +405,36 @@ void kcov_task_exit(struct task_struct *t)
        kcov = t->kcov;
        if (kcov == NULL)
                return;
+
        spin_lock(&kcov->lock);
+       kcov_debug("t = %px, kcov->t = %px\n", t, kcov->t);
+       /*
+        * For KCOV_ENABLE devices we want to make sure that t->kcov->t == t,
+        * which comes down to:
+        *        WARN_ON(!kcov->remote && kcov->t != t);
+        *
+        * For KCOV_REMOTE_ENABLE devices, the exiting task is either:
+        * 2. A remote task between kcov_remote_start() and kcov_remote_stop().
+        *    In this case we should print a warning right away, since a task
+        *    shouldn't be exiting when it's in a kcov coverage collection
+        *    section. Here t points to the task that is collecting remote
+        *    coverage, and t->kcov->t points to the thread that created the
+        *    kcov device. Which means that to detect this case we need to
+        *    check that t != t->kcov->t, and this gives us the following:
+        *        WARN_ON(kcov->remote && kcov->t != t);
+        *
+        * 2. The task that created kcov exiting without calling KCOV_DISABLE,
+        *    and then again we can make sure that t->kcov->t == t:
+        *        WARN_ON(kcov->remote && kcov->t != t);
+        *
+        * By combining all three checks into one we get:
+        */
        if (WARN_ON(kcov->t != t)) {
                spin_unlock(&kcov->lock);
                return;
        }
        /* Just to not leave dangling references behind. */
-       kcov_task_init(t);
-       kcov->t = NULL;
-       kcov->mode = KCOV_MODE_INIT;
+       kcov_disable(t, kcov);
        spin_unlock(&kcov->lock);
        kcov_put(kcov);
 }
@@ -313,6 +483,7 @@ static int kcov_open(struct inode *inode, struct file *filep)
        if (!kcov)
                return -ENOMEM;
        kcov->mode = KCOV_MODE_DISABLED;
+       kcov->sequence = 1;
        refcount_set(&kcov->refcount, 1);
        spin_lock_init(&kcov->lock);
        filep->private_data = kcov;
@@ -325,6 +496,20 @@ static int kcov_close(struct inode *inode, struct file *filep)
        return 0;
 }
 
+static int kcov_get_mode(unsigned long arg)
+{
+       if (arg == KCOV_TRACE_PC)
+               return KCOV_MODE_TRACE_PC;
+       else if (arg == KCOV_TRACE_CMP)
+#ifdef CONFIG_KCOV_ENABLE_COMPARISONS
+               return KCOV_MODE_TRACE_CMP;
+#else
+               return -ENOTSUPP;
+#endif
+       else
+               return -EINVAL;
+}
+
 /*
  * Fault in a lazily-faulted vmalloc area before it can be used by
  * __santizer_cov_trace_pc(), to avoid recursion issues if any code on the
@@ -340,14 +525,35 @@ static void kcov_fault_in_area(struct kcov *kcov)
                READ_ONCE(area[offset]);
 }
 
+static inline bool kcov_check_handle(u64 handle, bool common_valid,
+                               bool uncommon_valid, bool zero_valid)
+{
+       if (handle & ~(KCOV_SUBSYSTEM_MASK | KCOV_INSTANCE_MASK))
+               return false;
+       switch (handle & KCOV_SUBSYSTEM_MASK) {
+       case KCOV_SUBSYSTEM_COMMON:
+               return (handle & KCOV_INSTANCE_MASK) ?
+                       common_valid : zero_valid;
+       case KCOV_SUBSYSTEM_USB:
+               return uncommon_valid;
+       default:
+               return false;
+       }
+       return false;
+}
+
 static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
                             unsigned long arg)
 {
        struct task_struct *t;
        unsigned long size, unused;
+       int mode, i;
+       struct kcov_remote_arg *remote_arg;
+       struct kcov_remote *remote;
 
        switch (cmd) {
        case KCOV_INIT_TRACE:
+               kcov_debug("KCOV_INIT_TRACE\n");
                /*
                 * Enable kcov in trace mode and setup buffer size.
                 * Must happen before anything else.
@@ -366,6 +572,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
                kcov->mode = KCOV_MODE_INIT;
                return 0;
        case KCOV_ENABLE:
+               kcov_debug("KCOV_ENABLE\n");
                /*
                 * Enable coverage for the current task.
                 * At this point user must have been enabled trace mode,
@@ -378,29 +585,20 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
                t = current;
                if (kcov->t != NULL || t->kcov != NULL)
                        return -EBUSY;
-               if (arg == KCOV_TRACE_PC)
-                       kcov->mode = KCOV_MODE_TRACE_PC;
-               else if (arg == KCOV_TRACE_CMP)
-#ifdef CONFIG_KCOV_ENABLE_COMPARISONS
-                       kcov->mode = KCOV_MODE_TRACE_CMP;
-#else
-               return -ENOTSUPP;
-#endif
-               else
-                       return -EINVAL;
+               mode = kcov_get_mode(arg);
+               if (mode < 0)
+                       return mode;
                kcov_fault_in_area(kcov);
-               /* Cache in task struct for performance. */
-               t->kcov_size = kcov->size;
-               t->kcov_area = kcov->area;
-               /* See comment in check_kcov_mode(). */
-               barrier();
-               WRITE_ONCE(t->kcov_mode, kcov->mode);
+               kcov->mode = mode;
+               kcov_start(t, kcov->size, kcov->area, kcov->mode,
+                               kcov->sequence);
                t->kcov = kcov;
                kcov->t = t;
-               /* This is put either in kcov_task_exit() or in KCOV_DISABLE. */
+               /* Put either in kcov_task_exit() or in KCOV_DISABLE. */
                kcov_get(kcov);
                return 0;
        case KCOV_DISABLE:
+               kcov_debug("KCOV_DISABLE\n");
                /* Disable coverage for the current task. */
                unused = arg;
                if (unused != 0 || current->kcov != kcov)
@@ -408,11 +606,65 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
                t = current;
                if (WARN_ON(kcov->t != t))
                        return -EINVAL;
-               kcov_task_init(t);
-               kcov->t = NULL;
-               kcov->mode = KCOV_MODE_INIT;
+               kcov_disable(t, kcov);
                kcov_put(kcov);
                return 0;
+       case KCOV_REMOTE_ENABLE:
+               kcov_debug("KCOV_REMOTE_ENABLE\n");
+               if (kcov->mode != KCOV_MODE_INIT || !kcov->area)
+                       return -EINVAL;
+               t = current;
+               if (kcov->t != NULL || t->kcov != NULL)
+                       return -EBUSY;
+               remote_arg = (struct kcov_remote_arg *)arg;
+               mode = kcov_get_mode(remote_arg->trace_mode);
+               if (mode < 0)
+                       return mode;
+               if (remote_arg->area_size > LONG_MAX / sizeof(unsigned long))
+                       return -EINVAL;
+               kcov->mode = mode;
+               t->kcov = kcov;
+               kcov->t = t;
+               kcov->remote = true;
+               kcov->remote_size = remote_arg->area_size;
+               spin_lock(&kcov_remote_lock);
+               for (i = 0; i < remote_arg->num_handles; i++) {
+                       kcov_debug("handle %llx\n", remote_arg->handles[i]);
+                       if (!kcov_check_handle(remote_arg->handles[i],
+                                               false, true, false)) {
+                               spin_unlock(&kcov_remote_lock);
+                               kcov_disable(t, kcov);
+                               return -EINVAL;
+                       }
+                       remote = kcov_remote_add(kcov, remote_arg->handles[i]);
+                       if (IS_ERR(remote)) {
+                               spin_unlock(&kcov_remote_lock);
+                               kcov_disable(t, kcov);
+                               return PTR_ERR(remote);
+                       }
+               }
+               if (remote_arg->common_handle) {
+                       kcov_debug("common handle %llx\n",
+                                       remote_arg->common_handle);
+                       if (!kcov_check_handle(remote_arg->common_handle,
+                                               true, false, false)) {
+                               spin_unlock(&kcov_remote_lock);
+                               kcov_disable(t, kcov);
+                               return -EINVAL;
+                       }
+                       remote = kcov_remote_add(kcov,
+                                       remote_arg->common_handle);
+                       if (IS_ERR(remote)) {
+                               spin_unlock(&kcov_remote_lock);
+                               kcov_disable(t, kcov);
+                               return PTR_ERR(remote);
+                       }
+                       t->kcov_handle = remote_arg->common_handle;
+               }
+               spin_unlock(&kcov_remote_lock);
+               /* Put either in kcov_task_exit() or in KCOV_DISABLE. */
+               kcov_get(kcov);
+               return 0;
        default:
                return -ENOTTY;
        }
@@ -422,11 +674,35 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
        struct kcov *kcov;
        int res;
+       struct kcov_remote_arg *remote_arg = NULL;
+       unsigned int remote_num_handles;
+       unsigned long remote_arg_size;
+
+       if (cmd == KCOV_REMOTE_ENABLE) {
+               if (get_user(remote_num_handles, (unsigned __user *)(arg +
+                               offsetof(struct kcov_remote_arg, num_handles))))
+                       return -EFAULT;
+               if (remote_num_handles > KCOV_REMOTE_MAX_HANDLES)
+                       return -EINVAL;
+               remote_arg_size = struct_size(remote_arg, handles,
+                                       remote_num_handles);
+               remote_arg = memdup_user((void __user *)arg, remote_arg_size);
+               if (IS_ERR(remote_arg))
+                       return PTR_ERR(remote_arg);
+               if (remote_arg->num_handles != remote_num_handles) {
+                       kfree(remote_arg);
+                       return -EINVAL;
+               }
+               arg = (unsigned long)remote_arg;
+       }
 
        kcov = filep->private_data;
        spin_lock(&kcov->lock);
        res = kcov_ioctl_locked(kcov, cmd, arg);
        spin_unlock(&kcov->lock);
+
+       kfree(remote_arg);
+
        return res;
 }
 
@@ -438,6 +714,207 @@ static const struct file_operations kcov_fops = {
        .release        = kcov_close,
 };
 
+/*
+ * kcov_remote_start() and kcov_remote_stop() can be used to annotate a section
+ * of code in a kernel background thread to allow kcov to be used to collect
+ * coverage from that part of code.
+ *
+ * The handle argument of kcov_remote_start() identifies a code section that is
+ * used for coverage collection. A userspace process passes this handle to
+ * KCOV_REMOTE_ENABLE ioctl to make the used kcov device start collecting
+ * coverage for the code section identified by this handle.
+ *
+ * The usage of these annotations in the kernel code is different depending on
+ * the type of the kernel thread whose code is being annotated.
+ *
+ * For global kernel threads that are spawned in a limited number of instances
+ * (e.g. one USB hub_event() worker thread is spawned per USB HCD), each
+ * instance must be assigned a unique 4-byte instance id. The instance id is
+ * then combined with a 1-byte subsystem id to get a handle via
+ * kcov_remote_handle(subsystem_id, instance_id).
+ *
+ * For local kernel threads that are spawned from system calls handler when a
+ * user interacts with some kernel interface (e.g. vhost workers), a handle is
+ * passed from a userspace process as the common_handle field of the
+ * kcov_remote_arg struct (note, that the user must generate a handle by using
+ * kcov_remote_handle() with KCOV_SUBSYSTEM_COMMON as the subsystem id and an
+ * arbitrary 4-byte non-zero number as the instance id). This common handle
+ * then gets saved into the task_struct of the process that issued the
+ * KCOV_REMOTE_ENABLE ioctl. When this proccess issues system calls that spawn
+ * kernel threads, the common handle must be retrived via kcov_common_handle()
+ * and passed to the spawned threads via custom annotations. Those kernel
+ * threads must in turn be annotated with kcov_remote_start(common_handle) and
+ * kcov_remote_stop(). All of the threads that are spawned by the same process
+ * obtain the same handle, hence the name "common".
+ *
+ * See Documentation/dev-tools/kcov.rst for more details.
+ *
+ * Internally, this function looks up the kcov device associated with the
+ * provided handle, allocates an area for coverage collection, and saves the
+ * pointers to kcov and area into the current task_struct to allow coverage to
+ * be collected via __sanitizer_cov_trace_pc()
+ * In turns kcov_remote_stop() clears those pointers from task_struct to stop
+ * collecting coverage and copies all collected coverage into the kcov area.
+ */
+void kcov_remote_start(u64 handle)
+{
+       struct kcov_remote *remote;
+       void *area;
+       struct task_struct *t;
+       unsigned int size;
+       enum kcov_mode mode;
+       int sequence;
+
+       if (WARN_ON(!kcov_check_handle(handle, true, true, true)))
+               return;
+       if (WARN_ON(!in_task()))
+               return;
+       t = current;
+       /*
+        * Check that kcov_remote_start is not called twice
+        * nor called by user tasks (with enabled kcov).
+        */
+       if (WARN_ON(t->kcov))
+               return;
+
+       kcov_debug("handle = %llx\n", handle);
+
+       spin_lock(&kcov_remote_lock);
+       remote = kcov_remote_find(handle);
+       if (!remote) {
+               kcov_debug("no remote found");
+               spin_unlock(&kcov_remote_lock);
+               return;
+       }
+       /* Put in kcov_remote_stop(). */
+       kcov_get(remote->kcov);
+       t->kcov = remote->kcov;
+       /*
+        * Read kcov fields before unlock to prevent races with
+        * KCOV_DISABLE / kcov_remote_reset().
+        */
+       size = remote->kcov->remote_size;
+       mode = remote->kcov->mode;
+       sequence = remote->kcov->sequence;
+       area = kcov_remote_area_get(size);
+       spin_unlock(&kcov_remote_lock);
+
+       if (!area) {
+               area = vmalloc(size * sizeof(unsigned long));
+               if (!area) {
+                       t->kcov = NULL;
+                       kcov_put(remote->kcov);
+                       return;
+               }
+       }
+       /* Reset coverage size. */
+       *(u64 *)area = 0;
+
+       kcov_debug("area = %px, size = %u", area, size);
+
+       kcov_start(t, size, area, mode, sequence);
+
+}
+EXPORT_SYMBOL(kcov_remote_start);
+
+static void kcov_move_area(enum kcov_mode mode, void *dst_area,
+                               unsigned int dst_area_size, void *src_area)
+{
+       u64 word_size = sizeof(unsigned long);
+       u64 count_size, entry_size_log;
+       u64 dst_len, src_len;
+       void *dst_entries, *src_entries;
+       u64 dst_occupied, dst_free, bytes_to_move, entries_moved;
+
+       kcov_debug("%px %u <= %px %lu\n",
+               dst_area, dst_area_size, src_area, *(unsigned long *)src_area);
+
+       switch (mode) {
+       case KCOV_MODE_TRACE_PC:
+               dst_len = READ_ONCE(*(unsigned long *)dst_area);
+               src_len = *(unsigned long *)src_area;
+               count_size = sizeof(unsigned long);
+               entry_size_log = __ilog2_u64(sizeof(unsigned long));
+               break;
+       case KCOV_MODE_TRACE_CMP:
+               dst_len = READ_ONCE(*(u64 *)dst_area);
+               src_len = *(u64 *)src_area;
+               count_size = sizeof(u64);
+               BUILD_BUG_ON(!is_power_of_2(KCOV_WORDS_PER_CMP));
+               entry_size_log = __ilog2_u64(sizeof(u64) * KCOV_WORDS_PER_CMP);
+               break;
+       default:
+               WARN_ON(1);
+               return;
+       }
+
+       /* As arm can't divide u64 integers use log of entry size. */
+       if (dst_len > ((dst_area_size * word_size - count_size) >>
+                               entry_size_log))
+               return;
+       dst_occupied = count_size + (dst_len << entry_size_log);
+       dst_free = dst_area_size * word_size - dst_occupied;
+       bytes_to_move = min(dst_free, src_len << entry_size_log);
+       dst_entries = dst_area + dst_occupied;
+       src_entries = src_area + count_size;
+       memcpy(dst_entries, src_entries, bytes_to_move);
+       entries_moved = bytes_to_move >> entry_size_log;
+
+       switch (mode) {
+       case KCOV_MODE_TRACE_PC:
+               WRITE_ONCE(*(unsigned long *)dst_area, dst_len + entries_moved);
+               break;
+       case KCOV_MODE_TRACE_CMP:
+               WRITE_ONCE(*(u64 *)dst_area, dst_len + entries_moved);
+               break;
+       default:
+               break;
+       }
+}
+
+/* See the comment before kcov_remote_start() for usage details. */
+void kcov_remote_stop(void)
+{
+       struct task_struct *t = current;
+       struct kcov *kcov = t->kcov;
+       void *area = t->kcov_area;
+       unsigned int size = t->kcov_size;
+       int sequence = t->kcov_sequence;
+
+       if (!kcov) {
+               kcov_debug("no kcov found\n");
+               return;
+       }
+
+       kcov_stop(t);
+       t->kcov = NULL;
+
+       spin_lock(&kcov->lock);
+       /*
+        * KCOV_DISABLE could have been called between kcov_remote_start()
+        * and kcov_remote_stop(), hence the check.
+        */
+       kcov_debug("move if: %d == %d && %d\n",
+               sequence, kcov->sequence, (int)kcov->remote);
+       if (sequence == kcov->sequence && kcov->remote)
+               kcov_move_area(kcov->mode, kcov->area, kcov->size, area);
+       spin_unlock(&kcov->lock);
+
+       spin_lock(&kcov_remote_lock);
+       kcov_remote_area_put(area, size);
+       spin_unlock(&kcov_remote_lock);
+
+       kcov_put(kcov);
+}
+EXPORT_SYMBOL(kcov_remote_stop);
+
+/* See the comment before kcov_remote_start() for usage details. */
+u64 kcov_common_handle(void)
+{
+       return current->kcov_handle;
+}
+EXPORT_SYMBOL(kcov_common_handle);
+
 static int __init kcov_init(void)
 {
        /*
index 052a402..b56f322 100644 (file)
@@ -1033,6 +1033,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
        strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
 
        free_module(mod);
+       /* someone could wait for the module in add_unformed_module() */
+       wake_up_all(&module_wq);
        return 0;
 out:
        mutex_unlock(&module_mutex);
@@ -1400,7 +1402,7 @@ static int verify_namespace_is_imported(const struct load_info *info,
        char *imported_namespace;
 
        namespace = kernel_symbol_namespace(sym);
-       if (namespace) {
+       if (namespace && namespace[0]) {
                imported_namespace = get_modinfo(info, "import_ns");
                while (imported_namespace) {
                        if (strcmp(namespace, imported_namespace) == 0)
@@ -3728,6 +3730,7 @@ static int complete_formation(struct module *mod, struct load_info *info)
 
        module_enable_ro(mod, false);
        module_enable_nx(mod);
+       module_enable_x(mod);
 
        /* Mark state as coming so strong_try_module_get() ignores us,
         * but kallsyms etc. can see us. */
@@ -3750,11 +3753,6 @@ static int prepare_coming_module(struct module *mod)
        if (err)
                return err;
 
-       /* Make module executable after ftrace is enabled */
-       mutex_lock(&module_mutex);
-       module_enable_x(mod);
-       mutex_unlock(&module_mutex);
-
        blocking_notifier_call_chain(&module_notify_list,
                                     MODULE_STATE_COMING, mod);
        return 0;
index d9f5081..63d7501 100644 (file)
@@ -23,22 +23,10 @@ static int notifier_chain_register(struct notifier_block **nl,
                struct notifier_block *n)
 {
        while ((*nl) != NULL) {
-               WARN_ONCE(((*nl) == n), "double register detected");
-               if (n->priority > (*nl)->priority)
-                       break;
-               nl = &((*nl)->next);
-       }
-       n->next = *nl;
-       rcu_assign_pointer(*nl, n);
-       return 0;
-}
-
-static int notifier_chain_cond_register(struct notifier_block **nl,
-               struct notifier_block *n)
-{
-       while ((*nl) != NULL) {
-               if ((*nl) == n)
+               if (unlikely((*nl) == n)) {
+                       WARN(1, "double register detected");
                        return 0;
+               }
                if (n->priority > (*nl)->priority)
                        break;
                nl = &((*nl)->next);
@@ -233,29 +221,6 @@ int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
 EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
 
 /**
- *     blocking_notifier_chain_cond_register - Cond add notifier to a blocking notifier chain
- *     @nh: Pointer to head of the blocking notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to a blocking notifier chain, only if not already
- *     present in the chain.
- *     Must be called in process context.
- *
- *     Currently always returns zero.
- */
-int blocking_notifier_chain_cond_register(struct blocking_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       down_write(&nh->rwsem);
-       ret = notifier_chain_cond_register(&nh->head, n);
-       up_write(&nh->rwsem);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_cond_register);
-
-/**
  *     blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
  *     @nh: Pointer to head of the blocking notifier chain
  *     @n: Entry to remove from notifier chain
index a45cba7..83edf86 100644 (file)
@@ -714,8 +714,10 @@ s32 freq_qos_read_value(struct freq_constraints *qos,
  * @req: Constraint request to apply.
  * @action: Action to perform (add/update/remove).
  * @value: Value to assign to the QoS request.
+ *
+ * This is only meant to be called from inside pm_qos, not drivers.
  */
-static int freq_qos_apply(struct freq_qos_request *req,
+int freq_qos_apply(struct freq_qos_request *req,
                          enum pm_qos_req_action action, s32 value)
 {
        int ret;
index af7c94b..4b144b0 100644 (file)
@@ -336,7 +336,7 @@ static int profile_dead_cpu(unsigned int cpu)
        struct page *page;
        int i;
 
-       if (prof_cpu_mask != NULL)
+       if (cpumask_available(prof_cpu_mask))
                cpumask_clear_cpu(cpu, prof_cpu_mask);
 
        for (i = 0; i < 2; i++) {
@@ -373,7 +373,7 @@ static int profile_prepare_cpu(unsigned int cpu)
 
 static int profile_online_cpu(unsigned int cpu)
 {
-       if (prof_cpu_mask != NULL)
+       if (cpumask_available(prof_cpu_mask))
                cpumask_set_cpu(cpu, prof_cpu_mask);
 
        return 0;
@@ -403,7 +403,7 @@ void profile_tick(int type)
 {
        struct pt_regs *regs = get_irq_regs();
 
-       if (!user_mode(regs) && prof_cpu_mask != NULL &&
+       if (!user_mode(regs) && cpumask_available(prof_cpu_mask) &&
            cpumask_test_cpu(smp_processor_id(), prof_cpu_mask))
                profile_hit(type, (void *)profile_pc(regs));
 }
index 86800b4..322ca88 100644 (file)
@@ -915,7 +915,7 @@ static int __init sugov_register(void)
 {
        return cpufreq_register_governor(&schedutil_gov);
 }
-fs_initcall(sugov_register);
+core_initcall(sugov_register);
 
 #ifdef CONFIG_ENERGY_MODEL
 extern bool sched_energy_update;
index d3aef31..a9331f1 100644 (file)
@@ -1279,11 +1279,13 @@ SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
 
 SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
 {
-       struct oldold_utsname tmp = {};
+       struct oldold_utsname tmp;
 
        if (!name)
                return -EFAULT;
 
+       memset(&tmp, 0, sizeof(tmp));
+
        down_read(&uts_sem);
        memcpy(&tmp.sysname, &utsname()->sysname, __OLD_UTS_LEN);
        memcpy(&tmp.nodename, &utsname()->nodename, __OLD_UTS_LEN);
index cdf5afa..25a0fcf 100644 (file)
@@ -671,6 +671,15 @@ config HIST_TRIGGERS
          See Documentation/trace/histogram.rst.
          If in doubt, say N.
 
+config TRACE_EVENT_INJECT
+       bool "Trace event injection"
+       depends on TRACING
+       help
+         Allow user-space to inject a specific trace event into the ring
+         buffer. This is mainly used for testing purpose.
+
+         If unsure, say N.
+
 config MMIOTRACE_TEST
        tristate "Test module for mmiotrace"
        depends on MMIOTRACE && m
index c2b2148..0e63db6 100644 (file)
@@ -69,6 +69,7 @@ obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o
 endif
 obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
 obj-$(CONFIG_EVENT_TRACING) += trace_events_trigger.o
+obj-$(CONFIG_TRACE_EVENT_INJECT) += trace_events_inject.o
 obj-$(CONFIG_HIST_TRIGGERS) += trace_events_hist.o
 obj-$(CONFIG_BPF_EVENTS) += bpf_trace.o
 obj-$(CONFIG_KPROBE_EVENTS) += trace_kprobe.o
index 67e0c46..a265973 100644 (file)
@@ -101,6 +101,15 @@ int function_graph_enter(unsigned long ret, unsigned long func,
 {
        struct ftrace_graph_ent trace;
 
+       /*
+        * Skip graph tracing if the return location is served by direct trampoline,
+        * since call sequence and return addresses is unpredicatable anymore.
+        * Ex: BPF trampoline may call original function and may skip frame
+        * depending on type of BPF programs attached.
+        */
+       if (ftrace_direct_func_count &&
+           ftrace_find_rec_direct(ret - MCOUNT_INSN_SIZE))
+               return -EBUSY;
        trace.func = func;
        trace.depth = ++current->curr_ret_depth;
 
index 74439ab..ac99a35 100644 (file)
@@ -2364,7 +2364,7 @@ int ftrace_direct_func_count;
  * Search the direct_functions hash to see if the given instruction pointer
  * has a direct caller attached to it.
  */
-static unsigned long find_rec_direct(unsigned long ip)
+unsigned long ftrace_find_rec_direct(unsigned long ip)
 {
        struct ftrace_func_entry *entry;
 
@@ -2380,7 +2380,7 @@ static void call_direct_funcs(unsigned long ip, unsigned long pip,
 {
        unsigned long addr;
 
-       addr = find_rec_direct(ip);
+       addr = ftrace_find_rec_direct(ip);
        if (!addr)
                return;
 
@@ -2393,11 +2393,6 @@ struct ftrace_ops direct_ops = {
                          | FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_REGS
                          | FTRACE_OPS_FL_PERMANENT,
 };
-#else
-static inline unsigned long find_rec_direct(unsigned long ip)
-{
-       return 0;
-}
 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
 
 /**
@@ -2417,7 +2412,7 @@ unsigned long ftrace_get_addr_new(struct dyn_ftrace *rec)
 
        if ((rec->flags & FTRACE_FL_DIRECT) &&
            (ftrace_rec_count(rec) == 1)) {
-               addr = find_rec_direct(rec->ip);
+               addr = ftrace_find_rec_direct(rec->ip);
                if (addr)
                        return addr;
                WARN_ON_ONCE(1);
@@ -2458,7 +2453,7 @@ unsigned long ftrace_get_addr_curr(struct dyn_ftrace *rec)
 
        /* Direct calls take precedence over trampolines */
        if (rec->flags & FTRACE_FL_DIRECT_EN) {
-               addr = find_rec_direct(rec->ip);
+               addr = ftrace_find_rec_direct(rec->ip);
                if (addr)
                        return addr;
                WARN_ON_ONCE(1);
@@ -3604,7 +3599,7 @@ static int t_show(struct seq_file *m, void *v)
                if (rec->flags & FTRACE_FL_DIRECT) {
                        unsigned long direct;
 
-                       direct = find_rec_direct(rec->ip);
+                       direct = ftrace_find_rec_direct(rec->ip);
                        if (direct)
                                seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
                }
@@ -5008,7 +5003,7 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
        mutex_lock(&direct_mutex);
 
        /* See if there's a direct function at @ip already */
-       if (find_rec_direct(ip))
+       if (ftrace_find_rec_direct(ip))
                goto out_unlock;
 
        ret = -ENODEV;
@@ -5027,7 +5022,7 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
        if (ip != rec->ip) {
                ip = rec->ip;
                /* Need to check this ip for a direct. */
-               if (find_rec_direct(ip))
+               if (ftrace_find_rec_direct(ip))
                        goto out_unlock;
        }
 
index 66358d6..3f65537 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/trace_seq.h>
 #include <linux/spinlock.h>
 #include <linux/irq_work.h>
+#include <linux/security.h>
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 #include <linux/kthread.h>     /* for self test */
@@ -5068,6 +5069,11 @@ static __init int test_ringbuffer(void)
        int cpu;
        int ret = 0;
 
+       if (security_locked_down(LOCKDOWN_TRACEFS)) {
+               pr_warn("Lockdown is enabled, skipping ring buffer tests\n");
+               return 0;
+       }
+
        pr_info("Running ring buffer tests...\n");
 
        buffer = ring_buffer_alloc(RB_TEST_BUFFER_SIZE, RB_FL_OVERWRITE);
index 02a23a6..6c75410 100644 (file)
@@ -1888,6 +1888,12 @@ int __init register_tracer(struct tracer *type)
                return -1;
        }
 
+       if (security_locked_down(LOCKDOWN_TRACEFS)) {
+               pr_warn("Can not register tracer %s due to lockdown\n",
+                          type->name);
+               return -EPERM;
+       }
+
        mutex_lock(&trace_types_lock);
 
        tracing_selftest_running = true;
@@ -8789,6 +8795,11 @@ struct dentry *tracing_init_dentry(void)
 {
        struct trace_array *tr = &global_trace;
 
+       if (security_locked_down(LOCKDOWN_TRACEFS)) {
+               pr_warn("Tracing disabled due to lockdown\n");
+               return ERR_PTR(-EPERM);
+       }
+
        /* The top level trace array uses  NULL as parent */
        if (tr->dir)
                return NULL;
@@ -9231,6 +9242,12 @@ __init static int tracer_alloc_buffers(void)
        int ring_buf_size;
        int ret = -ENOMEM;
 
+
+       if (security_locked_down(LOCKDOWN_TRACEFS)) {
+               pr_warn("Tracing disabled due to lockdown\n");
+               return -EPERM;
+       }
+
        /*
         * Make sure we don't accidently add more trace options
         * than we have bits for.
index ca7fcca..63bf60f 100644 (file)
@@ -1601,6 +1601,7 @@ extern struct list_head ftrace_events;
 
 extern const struct file_operations event_trigger_fops;
 extern const struct file_operations event_hist_fops;
+extern const struct file_operations event_inject_fops;
 
 #ifdef CONFIG_HIST_TRIGGERS
 extern int register_trigger_hist_cmd(void);
index 6b3a69e..c6de3ce 100644 (file)
@@ -2044,6 +2044,12 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
        trace_create_file("format", 0444, file->dir, call,
                          &ftrace_event_format_fops);
 
+#ifdef CONFIG_TRACE_EVENT_INJECT
+       if (call->event.type && call->class->reg)
+               trace_create_file("inject", 0200, file->dir, file,
+                                 &event_inject_fops);
+#endif
+
        return 0;
 }
 
diff --git a/kernel/trace/trace_events_inject.c b/kernel/trace/trace_events_inject.c
new file mode 100644 (file)
index 0000000..d45079e
--- /dev/null
@@ -0,0 +1,329 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * trace_events_inject - trace event injection
+ *
+ * Copyright (C) 2019 Cong Wang <cwang@twitter.com>
+ */
+
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/rculist.h>
+
+#include "trace.h"
+
+static int
+trace_inject_entry(struct trace_event_file *file, void *rec, int len)
+{
+       struct trace_event_buffer fbuffer;
+       int written = 0;
+       void *entry;
+
+       rcu_read_lock_sched();
+       entry = trace_event_buffer_reserve(&fbuffer, file, len);
+       if (entry) {
+               memcpy(entry, rec, len);
+               written = len;
+               trace_event_buffer_commit(&fbuffer);
+       }
+       rcu_read_unlock_sched();
+
+       return written;
+}
+
+static int
+parse_field(char *str, struct trace_event_call *call,
+           struct ftrace_event_field **pf, u64 *pv)
+{
+       struct ftrace_event_field *field;
+       char *field_name;
+       int s, i = 0;
+       int len;
+       u64 val;
+
+       if (!str[i])
+               return 0;
+       /* First find the field to associate to */
+       while (isspace(str[i]))
+               i++;
+       s = i;
+       while (isalnum(str[i]) || str[i] == '_')
+               i++;
+       len = i - s;
+       if (!len)
+               return -EINVAL;
+
+       field_name = kmemdup_nul(str + s, len, GFP_KERNEL);
+       if (!field_name)
+               return -ENOMEM;
+       field = trace_find_event_field(call, field_name);
+       kfree(field_name);
+       if (!field)
+               return -ENOENT;
+
+       *pf = field;
+       while (isspace(str[i]))
+               i++;
+       if (str[i] != '=')
+               return -EINVAL;
+       i++;
+       while (isspace(str[i]))
+               i++;
+       s = i;
+       if (isdigit(str[i]) || str[i] == '-') {
+               char *num, c;
+               int ret;
+
+               /* Make sure the field is not a string */
+               if (is_string_field(field))
+                       return -EINVAL;
+
+               if (str[i] == '-')
+                       i++;
+
+               /* We allow 0xDEADBEEF */
+               while (isalnum(str[i]))
+                       i++;
+               num = str + s;
+               c = str[i];
+               if (c != '\0' && !isspace(c))
+                       return -EINVAL;
+               str[i] = '\0';
+               /* Make sure it is a value */
+               if (field->is_signed)
+                       ret = kstrtoll(num, 0, &val);
+               else
+                       ret = kstrtoull(num, 0, &val);
+               str[i] = c;
+               if (ret)
+                       return ret;
+
+               *pv = val;
+               return i;
+       } else if (str[i] == '\'' || str[i] == '"') {
+               char q = str[i];
+
+               /* Make sure the field is OK for strings */
+               if (!is_string_field(field))
+                       return -EINVAL;
+
+               for (i++; str[i]; i++) {
+                       if (str[i] == '\\' && str[i + 1]) {
+                               i++;
+                               continue;
+                       }
+                       if (str[i] == q)
+                               break;
+               }
+               if (!str[i])
+                       return -EINVAL;
+
+               /* Skip quotes */
+               s++;
+               len = i - s;
+               if (len >= MAX_FILTER_STR_VAL)
+                       return -EINVAL;
+
+               *pv = (unsigned long)(str + s);
+               str[i] = 0;
+               /* go past the last quote */
+               i++;
+               return i;
+       }
+
+       return -EINVAL;
+}
+
+static int trace_get_entry_size(struct trace_event_call *call)
+{
+       struct ftrace_event_field *field;
+       struct list_head *head;
+       int size = 0;
+
+       head = trace_get_fields(call);
+       list_for_each_entry(field, head, link) {
+               if (field->size + field->offset > size)
+                       size = field->size + field->offset;
+       }
+
+       return size;
+}
+
+static void *trace_alloc_entry(struct trace_event_call *call, int *size)
+{
+       int entry_size = trace_get_entry_size(call);
+       struct ftrace_event_field *field;
+       struct list_head *head;
+       void *entry = NULL;
+
+       /* We need an extra '\0' at the end. */
+       entry = kzalloc(entry_size + 1, GFP_KERNEL);
+       if (!entry)
+               return NULL;
+
+       head = trace_get_fields(call);
+       list_for_each_entry(field, head, link) {
+               if (!is_string_field(field))
+                       continue;
+               if (field->filter_type == FILTER_STATIC_STRING)
+                       continue;
+               if (field->filter_type == FILTER_DYN_STRING) {
+                       u32 *str_item;
+                       int str_loc = entry_size & 0xffff;
+
+                       str_item = (u32 *)(entry + field->offset);
+                       *str_item = str_loc; /* string length is 0. */
+               } else {
+                       char **paddr;
+
+                       paddr = (char **)(entry + field->offset);
+                       *paddr = "";
+               }
+       }
+
+       *size = entry_size + 1;
+       return entry;
+}
+
+#define INJECT_STRING "STATIC STRING CAN NOT BE INJECTED"
+
+/* Caller is responsible to free the *pentry. */
+static int parse_entry(char *str, struct trace_event_call *call, void **pentry)
+{
+       struct ftrace_event_field *field;
+       unsigned long irq_flags;
+       void *entry = NULL;
+       int entry_size;
+       u64 val;
+       int len;
+
+       entry = trace_alloc_entry(call, &entry_size);
+       *pentry = entry;
+       if (!entry)
+               return -ENOMEM;
+
+       local_save_flags(irq_flags);
+       tracing_generic_entry_update(entry, call->event.type, irq_flags,
+                                    preempt_count());
+
+       while ((len = parse_field(str, call, &field, &val)) > 0) {
+               if (is_function_field(field))
+                       return -EINVAL;
+
+               if (is_string_field(field)) {
+                       char *addr = (char *)(unsigned long) val;
+
+                       if (field->filter_type == FILTER_STATIC_STRING) {
+                               strlcpy(entry + field->offset, addr, field->size);
+                       } else if (field->filter_type == FILTER_DYN_STRING) {
+                               int str_len = strlen(addr) + 1;
+                               int str_loc = entry_size & 0xffff;
+                               u32 *str_item;
+
+                               entry_size += str_len;
+                               *pentry = krealloc(entry, entry_size, GFP_KERNEL);
+                               if (!*pentry) {
+                                       kfree(entry);
+                                       return -ENOMEM;
+                               }
+                               entry = *pentry;
+
+                               strlcpy(entry + (entry_size - str_len), addr, str_len);
+                               str_item = (u32 *)(entry + field->offset);
+                               *str_item = (str_len << 16) | str_loc;
+                       } else {
+                               char **paddr;
+
+                               paddr = (char **)(entry + field->offset);
+                               *paddr = INJECT_STRING;
+                       }
+               } else {
+                       switch (field->size) {
+                       case 1: {
+                               u8 tmp = (u8) val;
+
+                               memcpy(entry + field->offset, &tmp, 1);
+                               break;
+                       }
+                       case 2: {
+                               u16 tmp = (u16) val;
+
+                               memcpy(entry + field->offset, &tmp, 2);
+                               break;
+                       }
+                       case 4: {
+                               u32 tmp = (u32) val;
+
+                               memcpy(entry + field->offset, &tmp, 4);
+                               break;
+                       }
+                       case 8:
+                               memcpy(entry + field->offset, &val, 8);
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+               }
+
+               str += len;
+       }
+
+       if (len < 0)
+               return len;
+
+       return entry_size;
+}
+
+static ssize_t
+event_inject_write(struct file *filp, const char __user *ubuf, size_t cnt,
+                  loff_t *ppos)
+{
+       struct trace_event_call *call;
+       struct trace_event_file *file;
+       int err = -ENODEV, size;
+       void *entry = NULL;
+       char *buf;
+
+       if (cnt >= PAGE_SIZE)
+               return -EINVAL;
+
+       buf = memdup_user_nul(ubuf, cnt);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
+       strim(buf);
+
+       mutex_lock(&event_mutex);
+       file = event_file_data(filp);
+       if (file) {
+               call = file->event_call;
+               size = parse_entry(buf, call, &entry);
+               if (size < 0)
+                       err = size;
+               else
+                       err = trace_inject_entry(file, entry, size);
+       }
+       mutex_unlock(&event_mutex);
+
+       kfree(entry);
+       kfree(buf);
+
+       if (err < 0)
+               return err;
+
+       *ppos += err;
+       return cnt;
+}
+
+static ssize_t
+event_inject_read(struct file *file, char __user *buf, size_t size,
+                 loff_t *ppos)
+{
+       return -EPERM;
+}
+
+const struct file_operations event_inject_fops = {
+       .open = tracing_open_generic,
+       .read = event_inject_read,
+       .write = event_inject_write,
+};
index bc88fd9..cfc9235 100644 (file)
@@ -4374,8 +4374,8 @@ void destroy_workqueue(struct workqueue_struct *wq)
        for_each_pwq(pwq, wq) {
                spin_lock_irq(&pwq->pool->lock);
                if (WARN_ON(pwq_busy(pwq))) {
-                       pr_warning("%s: %s has the following busy pwq\n",
-                                  __func__, wq->name);
+                       pr_warn("%s: %s has the following busy pwq\n",
+                               __func__, wq->name);
                        show_pwq(pwq);
                        spin_unlock_irq(&pwq->pool->lock);
                        mutex_unlock(&wq->mutex);
index 6d7c587..6e790dc 100644 (file)
@@ -572,7 +572,7 @@ config OID_REGISTRY
          Enable fast lookup object identifier registry.
 
 config UCS2_STRING
-        tristate
+       tristate
 
 #
 # generic vdso
index 2f6fb96..d1842fe 100644 (file)
@@ -128,8 +128,8 @@ config DYNAMIC_DEBUG
          lineno : line number of the debug statement
          module : module that contains the debug statement
          function : function that contains the debug statement
-          flags : '=p' means the line is turned 'on' for printing
-          format : the format used for the debug statement
+         flags : '=p' means the line is turned 'on' for printing
+         format : the format used for the debug statement
 
          From a live system:
 
@@ -173,6 +173,15 @@ config SYMBOLIC_ERRNAME
          of the number 28. It makes the kernel image slightly larger
          (about 3KB), but can make the kernel logs easier to read.
 
+config DEBUG_BUGVERBOSE
+       bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT
+       depends on BUG && (GENERIC_BUG || HAVE_DEBUG_BUGVERBOSE)
+       default y
+       help
+         Say Y here to make BUG() panics output the file name and line number
+         of the BUG call as well as the EIP and oops trace.  This aids
+         debugging but costs about 70-100K of memory.
+
 endmenu # "printk and dmesg options"
 
 menu "Compile-time checks and compiler options"
@@ -181,7 +190,7 @@ config DEBUG_INFO
        bool "Compile the kernel with debug info"
        depends on DEBUG_KERNEL && !COMPILE_TEST
        help
-          If you say Y here the resulting kernel image will include
+         If you say Y here the resulting kernel image will include
          debugging info resulting in a larger kernel image.
          This adds debug symbols to the kernel and modules (gcc -g), and
          is needed if you intend to use kernel crashdump or binary object
@@ -278,25 +287,13 @@ config STRIP_ASM_SYMS
          get_wchan() and suchlike.
 
 config READABLE_ASM
-        bool "Generate readable assembler code"
-        depends on DEBUG_KERNEL
-        help
-          Disable some compiler optimizations that tend to generate human unreadable
-          assembler output. This may make the kernel slightly slower, but it helps
-          to keep kernel developers who have to stare a lot at assembler listings
-          sane.
-
-config DEBUG_FS
-       bool "Debug Filesystem"
+       bool "Generate readable assembler code"
+       depends on DEBUG_KERNEL
        help
-         debugfs is a virtual file system that kernel developers use to put
-         debugging files into.  Enable this option to be able to read and
-         write to these files.
-
-         For detailed documentation on the debugfs API, see
-         Documentation/filesystems/.
-
-         If unsure, say N.
+         Disable some compiler optimizations that tend to generate human unreadable
+         assembler output. This may make the kernel slightly slower, but it helps
+         to keep kernel developers who have to stare a lot at assembler listings
+         sane.
 
 config HEADERS_INSTALL
        bool "Install uapi headers to usr/include"
@@ -399,6 +396,8 @@ config DEBUG_FORCE_WEAK_PER_CPU
 
 endmenu # "Compiler options"
 
+menu "Generic Kernel Debugging Instruments"
+
 config MAGIC_SYSRQ
        bool "Magic SysRq key"
        depends on !UML
@@ -432,6 +431,24 @@ config MAGIC_SYSRQ_SERIAL
          This option allows you to decide whether you want to enable the
          magic SysRq key.
 
+config DEBUG_FS
+       bool "Debug Filesystem"
+       help
+         debugfs is a virtual file system that kernel developers use to put
+         debugging files into.  Enable this option to be able to read and
+         write to these files.
+
+         For detailed documentation on the debugfs API, see
+         Documentation/filesystems/.
+
+         If unsure, say N.
+
+source "lib/Kconfig.kgdb"
+
+source "lib/Kconfig.ubsan"
+
+endmenu
+
 config DEBUG_KERNEL
        bool "Kernel debugging"
        help
@@ -506,11 +523,11 @@ config DEBUG_OBJECTS_PERCPU_COUNTER
 
 config DEBUG_OBJECTS_ENABLE_DEFAULT
        int "debug_objects bootup default value (0-1)"
-        range 0 1
-        default "1"
-        depends on DEBUG_OBJECTS
-        help
-          Debug objects boot parameter default value
+       range 0 1
+       default "1"
+       depends on DEBUG_OBJECTS
+       help
+         Debug objects boot parameter default value
 
 config DEBUG_SLAB
        bool "Debug slab memory allocations"
@@ -624,12 +641,24 @@ config DEBUG_STACK_USAGE
 
          This option will slow down process creation somewhat.
 
+config SCHED_STACK_END_CHECK
+       bool "Detect stack corruption on calls to schedule()"
+       depends on DEBUG_KERNEL
+       default n
+       help
+         This option checks for a stack overrun on calls to schedule().
+         If the stack end location is found to be over written always panic as
+         the content of the corrupted region can no longer be trusted.
+         This is to ensure no erroneous behaviour occurs which could result in
+         data corruption or a sporadic crash at a later stage once the region
+         is examined. The runtime overhead introduced is minimal.
+
 config DEBUG_VM
        bool "Debug VM"
        depends on DEBUG_KERNEL
        help
          Enable this to turn on extended checks in the virtual-memory system
-          that may impact performance.
+         that may impact performance.
 
          If unsure, say N.
 
@@ -756,53 +785,6 @@ source "lib/Kconfig.kasan"
 
 endmenu # "Memory Debugging"
 
-config ARCH_HAS_KCOV
-       bool
-       help
-         An architecture should select this when it can successfully
-         build and run with CONFIG_KCOV. This typically requires
-         disabling instrumentation for some early boot code.
-
-config CC_HAS_SANCOV_TRACE_PC
-       def_bool $(cc-option,-fsanitize-coverage=trace-pc)
-
-config KCOV
-       bool "Code coverage for fuzzing"
-       depends on ARCH_HAS_KCOV
-       depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS
-       select DEBUG_FS
-       select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC
-       help
-         KCOV exposes kernel code coverage information in a form suitable
-         for coverage-guided fuzzing (randomized testing).
-
-         If RANDOMIZE_BASE is enabled, PC values will not be stable across
-         different machines and across reboots. If you need stable PC values,
-         disable RANDOMIZE_BASE.
-
-         For more details, see Documentation/dev-tools/kcov.rst.
-
-config KCOV_ENABLE_COMPARISONS
-       bool "Enable comparison operands collection by KCOV"
-       depends on KCOV
-       depends on $(cc-option,-fsanitize-coverage=trace-cmp)
-       help
-         KCOV also exposes operands of every comparison in the instrumented
-         code along with operand sizes and PCs of the comparison instructions.
-         These operands can be used by fuzzing engines to improve the quality
-         of fuzzing coverage.
-
-config KCOV_INSTRUMENT_ALL
-       bool "Instrument all code by default"
-       depends on KCOV
-       default y
-       help
-         If you are doing generic system call fuzzing (like e.g. syzkaller),
-         then you will want to instrument the whole kernel and you should
-         say y here. If you are doing more targeted fuzzing (like e.g.
-         filesystem fuzzing with AFL) then you will want to enable coverage
-         for more specific subsets of files, and should say n here.
-
 config DEBUG_SHIRQ
        bool "Debug shared IRQ handlers"
        depends on DEBUG_KERNEL
@@ -812,7 +794,35 @@ config DEBUG_SHIRQ
          Drivers ought to be able to handle interrupts coming in at those
          points; some don't and need to be caught.
 
-menu "Debug Lockups and Hangs"
+menu "Debug Oops, Lockups and Hangs"
+
+config PANIC_ON_OOPS
+       bool "Panic on Oops"
+       help
+         Say Y here to enable the kernel to panic when it oopses. This
+         has the same effect as setting oops=panic on the kernel command
+         line.
+
+         This feature is useful to ensure that the kernel does not do
+         anything erroneous after an oops which could result in data
+         corruption or other issues.
+
+         Say N if unsure.
+
+config PANIC_ON_OOPS_VALUE
+       int
+       range 0 1
+       default 0 if !PANIC_ON_OOPS
+       default 1 if PANIC_ON_OOPS
+
+config PANIC_TIMEOUT
+       int "panic timeout"
+       default 0
+       help
+         Set the timeout value (in seconds) until a reboot occurs when the
+         the kernel panics. If n = 0, then we wait forever. A timeout
+         value n > 0 will wait n seconds before rebooting, while a timeout
+         value n < 0 will reboot immediately.
 
 config LOCKUP_DETECTOR
        bool
@@ -970,33 +980,7 @@ config WQ_WATCHDOG
 
 endmenu # "Debug lockups and hangs"
 
-config PANIC_ON_OOPS
-       bool "Panic on Oops"
-       help
-         Say Y here to enable the kernel to panic when it oopses. This
-         has the same effect as setting oops=panic on the kernel command
-         line.
-
-         This feature is useful to ensure that the kernel does not do
-         anything erroneous after an oops which could result in data
-         corruption or other issues.
-
-         Say N if unsure.
-
-config PANIC_ON_OOPS_VALUE
-       int
-       range 0 1
-       default 0 if !PANIC_ON_OOPS
-       default 1 if PANIC_ON_OOPS
-
-config PANIC_TIMEOUT
-       int "panic timeout"
-       default 0
-       help
-         Set the timeout value (in seconds) until a reboot occurs when the
-         the kernel panics. If n = 0, then we wait forever. A timeout
-         value n > 0 will wait n seconds before rebooting, while a timeout
-         value n < 0 will reboot immediately.
+menu "Scheduler Debugging"
 
 config SCHED_DEBUG
        bool "Collect scheduler debugging info"
@@ -1024,17 +1008,7 @@ config SCHEDSTATS
          application, you can say N to avoid the very slight overhead
          this adds.
 
-config SCHED_STACK_END_CHECK
-       bool "Detect stack corruption on calls to schedule()"
-       depends on DEBUG_KERNEL
-       default n
-       help
-         This option checks for a stack overrun on calls to schedule().
-         If the stack end location is found to be over written always panic as
-         the content of the corrupted region can no longer be trusted.
-         This is to ensure no erroneous behaviour occurs which could result in
-         data corruption or a sporadic crash at a later stage once the region
-         is examined. The runtime overhead introduced is minimal.
+endmenu
 
 config DEBUG_TIMEKEEPING
        bool "Enable extra timekeeping sanity checking"
@@ -1338,14 +1312,7 @@ config DEBUG_KOBJECT_RELEASE
 config HAVE_DEBUG_BUGVERBOSE
        bool
 
-config DEBUG_BUGVERBOSE
-       bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT
-       depends on BUG && (GENERIC_BUG || HAVE_DEBUG_BUGVERBOSE)
-       default y
-       help
-         Say Y here to make BUG() panics output the file name and line number
-         of the BUG call as well as the EIP and oops trace.  This aids
-         debugging but costs about 70-100K of memory.
+menu "Debug kernel data structures"
 
 config DEBUG_LIST
        bool "Debug linked list manipulation"
@@ -1386,6 +1353,18 @@ config DEBUG_NOTIFIERS
          This is a relatively cheap check but if you care about maximum
          performance, say N.
 
+config BUG_ON_DATA_CORRUPTION
+       bool "Trigger a BUG when data corruption is detected"
+       select DEBUG_LIST
+       help
+         Select this option if the kernel should BUG when it encounters
+         data corruption in kernel memory structures when they get checked
+         for validity.
+
+         If unsure, say N.
+
+endmenu
+
 config DEBUG_CREDENTIALS
        bool "Debug credential management"
        depends on DEBUG_KERNEL
@@ -1419,7 +1398,7 @@ config DEBUG_WQ_FORCE_RR_CPU
          be impacted.
 
 config DEBUG_BLOCK_EXT_DEVT
-        bool "Force extended block device numbers and spread them"
+       bool "Force extended block device numbers and spread them"
        depends on DEBUG_KERNEL
        depends on BLOCK
        default n
@@ -1458,6 +1437,54 @@ config CPU_HOTPLUG_STATE_CONTROL
 
          Say N if your are unsure.
 
+config LATENCYTOP
+       bool "Latency measuring infrastructure"
+       depends on DEBUG_KERNEL
+       depends on STACKTRACE_SUPPORT
+       depends on PROC_FS
+       select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM && !ARC && !X86
+       select KALLSYMS
+       select KALLSYMS_ALL
+       select STACKTRACE
+       select SCHEDSTATS
+       select SCHED_DEBUG
+       help
+         Enable this option if you want to use the LatencyTOP tool
+         to find out which userspace is blocking on what kernel operations.
+
+source "kernel/trace/Kconfig"
+
+config PROVIDE_OHCI1394_DMA_INIT
+       bool "Remote debugging over FireWire early on boot"
+       depends on PCI && X86
+       help
+         If you want to debug problems which hang or crash the kernel early
+         on boot and the crashing machine has a FireWire port, you can use
+         this feature to remotely access the memory of the crashed machine
+         over FireWire. This employs remote DMA as part of the OHCI1394
+         specification which is now the standard for FireWire controllers.
+
+         With remote DMA, you can monitor the printk buffer remotely using
+         firescope and access all memory below 4GB using fireproxy from gdb.
+         Even controlling a kernel debugger is possible using remote DMA.
+
+         Usage:
+
+         If ohci1394_dma=early is used as boot parameter, it will initialize
+         all OHCI1394 controllers which are found in the PCI config space.
+
+         As all changes to the FireWire bus such as enabling and disabling
+         devices cause a bus reset and thereby disable remote DMA for all
+         devices, be sure to have the cable plugged and FireWire enabled on
+         the debugging host before booting the debug target for debugging.
+
+         This code (~1k) is freed after boot. By then, the firewire stack
+         in charge of the OHCI-1394 controllers should be used instead.
+
+         See Documentation/debugging-via-ohci1394.txt for more information.
+
+source "lib/kunit/Kconfig"
+
 config NOTIFIER_ERROR_INJECTION
        tristate "Notifier error injection"
        depends on DEBUG_KERNEL
@@ -1616,53 +1643,57 @@ config FAULT_INJECTION_STACKTRACE_FILTER
        help
          Provide stacktrace filter for fault-injection capabilities
 
-config LATENCYTOP
-       bool "Latency measuring infrastructure"
-       depends on DEBUG_KERNEL
-       depends on STACKTRACE_SUPPORT
-       depends on PROC_FS
-       select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM && !ARC && !X86
-       select KALLSYMS
-       select KALLSYMS_ALL
-       select STACKTRACE
-       select SCHEDSTATS
-       select SCHED_DEBUG
-       help
-         Enable this option if you want to use the LatencyTOP tool
-         to find out which userspace is blocking on what kernel operations.
+endmenu # "Kernel Testing and Coverage"
 
-source "kernel/trace/Kconfig"
+menu "Kernel Testing and Coverage"
 
-config PROVIDE_OHCI1394_DMA_INIT
-       bool "Remote debugging over FireWire early on boot"
-       depends on PCI && X86
+config ARCH_HAS_KCOV
+       bool
        help
-         If you want to debug problems which hang or crash the kernel early
-         on boot and the crashing machine has a FireWire port, you can use
-         this feature to remotely access the memory of the crashed machine
-         over FireWire. This employs remote DMA as part of the OHCI1394
-         specification which is now the standard for FireWire controllers.
+         An architecture should select this when it can successfully
+         build and run with CONFIG_KCOV. This typically requires
+         disabling instrumentation for some early boot code.
 
-         With remote DMA, you can monitor the printk buffer remotely using
-         firescope and access all memory below 4GB using fireproxy from gdb.
-         Even controlling a kernel debugger is possible using remote DMA.
+config CC_HAS_SANCOV_TRACE_PC
+       def_bool $(cc-option,-fsanitize-coverage=trace-pc)
 
-         Usage:
 
-         If ohci1394_dma=early is used as boot parameter, it will initialize
-         all OHCI1394 controllers which are found in the PCI config space.
+config KCOV
+       bool "Code coverage for fuzzing"
+       depends on ARCH_HAS_KCOV
+       depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS
+       select DEBUG_FS
+       select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC
+       help
+         KCOV exposes kernel code coverage information in a form suitable
+         for coverage-guided fuzzing (randomized testing).
 
-         As all changes to the FireWire bus such as enabling and disabling
-         devices cause a bus reset and thereby disable remote DMA for all
-         devices, be sure to have the cable plugged and FireWire enabled on
-         the debugging host before booting the debug target for debugging.
+         If RANDOMIZE_BASE is enabled, PC values will not be stable across
+         different machines and across reboots. If you need stable PC values,
+         disable RANDOMIZE_BASE.
 
-         This code (~1k) is freed after boot. By then, the firewire stack
-         in charge of the OHCI-1394 controllers should be used instead.
+         For more details, see Documentation/dev-tools/kcov.rst.
 
-         See Documentation/debugging-via-ohci1394.txt for more information.
+config KCOV_ENABLE_COMPARISONS
+       bool "Enable comparison operands collection by KCOV"
+       depends on KCOV
+       depends on $(cc-option,-fsanitize-coverage=trace-cmp)
+       help
+         KCOV also exposes operands of every comparison in the instrumented
+         code along with operand sizes and PCs of the comparison instructions.
+         These operands can be used by fuzzing engines to improve the quality
+         of fuzzing coverage.
 
-source "lib/kunit/Kconfig"
+config KCOV_INSTRUMENT_ALL
+       bool "Instrument all code by default"
+       depends on KCOV
+       default y
+       help
+         If you are doing generic system call fuzzing (like e.g. syzkaller),
+         then you will want to instrument the whole kernel and you should
+         say y here. If you are doing more targeted fuzzing (like e.g.
+         filesystem fuzzing with AFL) then you will want to enable coverage
+         for more specific subsets of files, and should say n here.
 
 menuconfig RUNTIME_TESTING_MENU
        bool "Runtime Testing"
@@ -2099,22 +2130,8 @@ config MEMTEST
                memtest=17, mean do 17 test patterns.
          If you are unsure how to answer this question, answer N.
 
-config BUG_ON_DATA_CORRUPTION
-       bool "Trigger a BUG when data corruption is detected"
-       select DEBUG_LIST
-       help
-         Select this option if the kernel should BUG when it encounters
-         data corruption in kernel memory structures when they get checked
-         for validity.
-
-         If unsure, say N.
-
 source "samples/Kconfig"
 
-source "lib/Kconfig.kgdb"
-
-source "lib/Kconfig.ubsan"
-
 config ARCH_HAS_DEVMEM_IS_ALLOWED
        bool
 
@@ -2154,8 +2171,12 @@ config IO_STRICT_DEVMEM
 
          If in doubt, say Y.
 
+menu "$(SRCARCH) Debugging"
+
 source "arch/$(SRCARCH)/Kconfig.debug"
 
+endmenu
+
 config HYPERV_TESTING
        bool "Microsoft Hyper-V driver testing"
        default n
index bbe397d..933680b 100644 (file)
@@ -64,9 +64,9 @@ config KGDB_LOW_LEVEL_TRAP
        depends on X86 || MIPS
        default n
        help
-         This will add an extra call back to kgdb for the breakpoint
-         exception handler which will allow kgdb to step through a
-         notify handler.
+        This will add an extra call back to kgdb for the breakpoint
+        exception handler which will allow kgdb to step through a
+        notify handler.
 
 config KGDB_KDB
        bool "KGDB_KDB: include kdb frontend for kgdb"
@@ -96,7 +96,7 @@ config KDB_DEFAULT_ENABLE
 
          The config option merely sets the default at boot time. Both
          issuing 'echo X > /sys/module/kdb/parameters/cmd_enable' or
-          setting with kdb.cmd_enable=X kernel command line option will
+         setting with kdb.cmd_enable=X kernel command line option will
          override the default settings.
 
 config KDB_KEYBOARD
index c2f0e2a..93217d4 100644 (file)
@@ -109,7 +109,7 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
 obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o
 obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
 
-obj-y += logic_pio.o
+lib-y += logic_pio.o
 
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
 
index f9e8348..4250519 100644 (file)
@@ -222,6 +222,18 @@ int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
 }
 EXPORT_SYMBOL(__bitmap_andnot);
 
+void __bitmap_replace(unsigned long *dst,
+                     const unsigned long *old, const unsigned long *new,
+                     const unsigned long *mask, unsigned int nbits)
+{
+       unsigned int k;
+       unsigned int nr = BITS_TO_LONGS(nbits);
+
+       for (k = 0; k < nr; k++)
+               dst[k] = (old[k] & ~mask[k]) | (new[k] & mask[k]);
+}
+EXPORT_SYMBOL(__bitmap_replace);
+
 int __bitmap_intersects(const unsigned long *bitmap1,
                        const unsigned long *bitmap2, unsigned int bits)
 {
index 5c51eb4..e35a76b 100644 (file)
@@ -214,3 +214,17 @@ EXPORT_SYMBOL(find_next_bit_le);
 #endif
 
 #endif /* __BIG_ENDIAN */
+
+unsigned long find_next_clump8(unsigned long *clump, const unsigned long *addr,
+                              unsigned long size, unsigned long offset)
+{
+       offset = find_next_bit(addr, size, offset);
+       if (offset == size)
+               return size;
+
+       offset = round_down(offset, 8);
+       *clump = bitmap_get_value8(addr, offset);
+
+       return offset;
+}
+EXPORT_SYMBOL(find_next_clump8);
index 24d20ca..7f1244b 100644 (file)
@@ -540,7 +540,7 @@ void gen_pool_for_each_chunk(struct gen_pool *pool,
 EXPORT_SYMBOL(gen_pool_for_each_chunk);
 
 /**
- * addr_in_gen_pool - checks if an address falls within the range of a pool
+ * gen_pool_has_addr - checks if an address falls within the range of a pool
  * @pool:      the generic memory pool
  * @start:     start address
  * @size:      size of the region
@@ -548,7 +548,7 @@ EXPORT_SYMBOL(gen_pool_for_each_chunk);
  * Check if the range of addresses falls within the specified pool. Returns
  * true if the entire range is contained in the pool and false otherwise.
  */
-bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start,
+bool gen_pool_has_addr(struct gen_pool *pool, unsigned long start,
                        size_t size)
 {
        bool found = false;
@@ -567,6 +567,7 @@ bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start,
        rcu_read_unlock();
        return found;
 }
+EXPORT_SYMBOL(gen_pool_has_addr);
 
 /**
  * gen_pool_avail - get available free space of the pool
index 9050275..f511a99 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2017 HiSilicon Limited, All Rights Reserved.
  * Author: Gabriele Paoloni <gabriele.paoloni@huawei.com>
  * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
+ * Author: John Garry <john.garry@huawei.com>
  */
 
 #define pr_fmt(fmt)    "LOGIC PIO: " fmt
@@ -39,7 +40,8 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
        resource_size_t iio_sz = MMIO_UPPER_LIMIT;
        int ret = 0;
 
-       if (!new_range || !new_range->fwnode || !new_range->size)
+       if (!new_range || !new_range->fwnode || !new_range->size ||
+           (new_range->flags == LOGIC_PIO_INDIRECT && !new_range->ops))
                return -EINVAL;
 
        start = new_range->hw_start;
@@ -237,7 +239,7 @@ type logic_in##bw(unsigned long addr)                                       \
        } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
                struct logic_pio_hwaddr *entry = find_io_range(addr);   \
                                                                        \
-               if (entry && entry->ops)                                \
+               if (entry)                                              \
                        ret = entry->ops->in(entry->hostdata,           \
                                        addr, sizeof(type));            \
                else                                                    \
@@ -253,7 +255,7 @@ void logic_out##bw(type value, unsigned long addr)                  \
        } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
                struct logic_pio_hwaddr *entry = find_io_range(addr);   \
                                                                        \
-               if (entry && entry->ops)                                \
+               if (entry)                                              \
                        entry->ops->out(entry->hostdata,                \
                                        addr, value, sizeof(type));     \
                else                                                    \
@@ -261,7 +263,7 @@ void logic_out##bw(type value, unsigned long addr)                  \
        }                                                               \
 }                                                                      \
                                                                        \
-void logic_ins##bw(unsigned long addr, void *buffer,           \
+void logic_ins##bw(unsigned long addr, void *buffer,                   \
                   unsigned int count)                                  \
 {                                                                      \
        if (addr < MMIO_UPPER_LIMIT) {                                  \
@@ -269,7 +271,7 @@ void logic_ins##bw(unsigned long addr, void *buffer,                \
        } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
                struct logic_pio_hwaddr *entry = find_io_range(addr);   \
                                                                        \
-               if (entry && entry->ops)                                \
+               if (entry)                                              \
                        entry->ops->ins(entry->hostdata,                \
                                addr, buffer, sizeof(type), count);     \
                else                                                    \
@@ -286,7 +288,7 @@ void logic_outs##bw(unsigned long addr, const void *buffer,         \
        } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
                struct logic_pio_hwaddr *entry = find_io_range(addr);   \
                                                                        \
-               if (entry && entry->ops)                                \
+               if (entry)                                              \
                        entry->ops->outs(entry->hostdata,               \
                                addr, buffer, sizeof(type), count);     \
                else                                                    \
index ba74436..31fb27d 100644 (file)
@@ -3,6 +3,7 @@
  * rational fractions
  *
  * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <oskar@scara.com>
+ * Copyright (C) 2019 Trent Piepho <tpiepho@gmail.com>
  *
  * helper functions when coping with rational numbers
  */
@@ -10,6 +11,7 @@
 #include <linux/rational.h>
 #include <linux/compiler.h>
 #include <linux/export.h>
+#include <linux/kernel.h>
 
 /*
  * calculate best rational approximation for a given fraction
@@ -33,30 +35,65 @@ void rational_best_approximation(
        unsigned long max_numerator, unsigned long max_denominator,
        unsigned long *best_numerator, unsigned long *best_denominator)
 {
-       unsigned long n, d, n0, d0, n1, d1;
+       /* n/d is the starting rational, which is continually
+        * decreased each iteration using the Euclidean algorithm.
+        *
+        * dp is the value of d from the prior iteration.
+        *
+        * n2/d2, n1/d1, and n0/d0 are our successively more accurate
+        * approximations of the rational.  They are, respectively,
+        * the current, previous, and two prior iterations of it.
+        *
+        * a is current term of the continued fraction.
+        */
+       unsigned long n, d, n0, d0, n1, d1, n2, d2;
        n = given_numerator;
        d = given_denominator;
        n0 = d1 = 0;
        n1 = d0 = 1;
+
        for (;;) {
-               unsigned long t, a;
-               if ((n1 > max_numerator) || (d1 > max_denominator)) {
-                       n1 = n0;
-                       d1 = d0;
-                       break;
-               }
+               unsigned long dp, a;
+
                if (d == 0)
                        break;
-               t = d;
+               /* Find next term in continued fraction, 'a', via
+                * Euclidean algorithm.
+                */
+               dp = d;
                a = n / d;
                d = n % d;
-               n = t;
-               t = n0 + a * n1;
+               n = dp;
+
+               /* Calculate the current rational approximation (aka
+                * convergent), n2/d2, using the term just found and
+                * the two prior approximations.
+                */
+               n2 = n0 + a * n1;
+               d2 = d0 + a * d1;
+
+               /* If the current convergent exceeds the maxes, then
+                * return either the previous convergent or the
+                * largest semi-convergent, the final term of which is
+                * found below as 't'.
+                */
+               if ((n2 > max_numerator) || (d2 > max_denominator)) {
+                       unsigned long t = min((max_numerator - n0) / n1,
+                                             (max_denominator - d0) / d1);
+
+                       /* This tests if the semi-convergent is closer
+                        * than the previous convergent.
+                        */
+                       if (2u * t > a || (2u * t == a && d0 * dp > d1 * d)) {
+                               n1 = n0 + t * n1;
+                               d1 = d0 + t * d1;
+                       }
+                       break;
+               }
                n0 = n1;
-               n1 = t;
-               t = d0 + a * d1;
+               n1 = n2;
                d0 = d1;
-               d1 = t;
+               d1 = d2;
        }
        *best_numerator = n1;
        *best_denominator = d1;
index c6aa036..0809805 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
        for (i = 0; i < rep; ++i) {
                tmp = $0
                gsub(/\$\$/, i, tmp)
-               gsub(/\$\#/, n, tmp)
+               gsub(/\$#/, n, tmp)
                gsub(/\$\*/, "$", tmp)
                print tmp
        }
index 51a98f7..e14a15a 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Test cases for printf facility.
+ * Test cases for bitmap API.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -21,6 +21,39 @@ static unsigned failed_tests __initdata;
 
 static char pbl_buffer[PAGE_SIZE] __initdata;
 
+static const unsigned long exp1[] __initconst = {
+       BITMAP_FROM_U64(1),
+       BITMAP_FROM_U64(2),
+       BITMAP_FROM_U64(0x0000ffff),
+       BITMAP_FROM_U64(0xffff0000),
+       BITMAP_FROM_U64(0x55555555),
+       BITMAP_FROM_U64(0xaaaaaaaa),
+       BITMAP_FROM_U64(0x11111111),
+       BITMAP_FROM_U64(0x22222222),
+       BITMAP_FROM_U64(0xffffffff),
+       BITMAP_FROM_U64(0xfffffffe),
+       BITMAP_FROM_U64(0x3333333311111111ULL),
+       BITMAP_FROM_U64(0xffffffff77777777ULL),
+       BITMAP_FROM_U64(0),
+};
+
+static const unsigned long exp2[] __initconst = {
+       BITMAP_FROM_U64(0x3333333311111111ULL),
+       BITMAP_FROM_U64(0xffffffff77777777ULL),
+};
+
+/* Fibonacci sequence */
+static const unsigned long exp2_to_exp3_mask[] __initconst = {
+       BITMAP_FROM_U64(0x008000020020212eULL),
+};
+/* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */
+static const unsigned long exp3_0_1[] __initconst = {
+       BITMAP_FROM_U64(0x33b3333311313137ULL),
+};
+/* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */
+static const unsigned long exp3_1_0[] __initconst = {
+       BITMAP_FROM_U64(0xff7fffff77575751ULL),
+};
 
 static bool __init
 __check_eq_uint(const char *srcfile, unsigned int line,
@@ -92,6 +125,36 @@ __check_eq_u32_array(const char *srcfile, unsigned int line,
        return true;
 }
 
+static bool __init __check_eq_clump8(const char *srcfile, unsigned int line,
+                                   const unsigned int offset,
+                                   const unsigned int size,
+                                   const unsigned char *const clump_exp,
+                                   const unsigned long *const clump)
+{
+       unsigned long exp;
+
+       if (offset >= size) {
+               pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n",
+                       srcfile, line, size, offset);
+               return false;
+       }
+
+       exp = clump_exp[offset / 8];
+       if (!exp) {
+               pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0",
+                       srcfile, line, offset);
+               return false;
+       }
+
+       if (*clump != exp) {
+               pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX",
+                       srcfile, line, exp, *clump);
+               return false;
+       }
+
+       return true;
+}
+
 #define __expect_eq(suffix, ...)                                       \
        ({                                                              \
                int result = 0;                                         \
@@ -108,6 +171,7 @@ __check_eq_u32_array(const char *srcfile, unsigned int line,
 #define expect_eq_bitmap(...)          __expect_eq(bitmap, ##__VA_ARGS__)
 #define expect_eq_pbl(...)             __expect_eq(pbl, ##__VA_ARGS__)
 #define expect_eq_u32_array(...)       __expect_eq(u32_array, ##__VA_ARGS__)
+#define expect_eq_clump8(...)          __expect_eq(clump8, ##__VA_ARGS__)
 
 static void __init test_zero_clear(void)
 {
@@ -206,6 +270,30 @@ static void __init test_copy(void)
        expect_eq_pbl("0-108,128-1023", bmap2, 1024);
 }
 
+#define EXP2_IN_BITS   (sizeof(exp2) * 8)
+
+static void __init test_replace(void)
+{
+       unsigned int nbits = 64;
+       DECLARE_BITMAP(bmap, 1024);
+
+       bitmap_zero(bmap, 1024);
+       bitmap_replace(bmap, &exp2[0], &exp2[1], exp2_to_exp3_mask, nbits);
+       expect_eq_bitmap(bmap, exp3_0_1, nbits);
+
+       bitmap_zero(bmap, 1024);
+       bitmap_replace(bmap, &exp2[1], &exp2[0], exp2_to_exp3_mask, nbits);
+       expect_eq_bitmap(bmap, exp3_1_0, nbits);
+
+       bitmap_fill(bmap, 1024);
+       bitmap_replace(bmap, &exp2[0], &exp2[1], exp2_to_exp3_mask, nbits);
+       expect_eq_bitmap(bmap, exp3_0_1, nbits);
+
+       bitmap_fill(bmap, 1024);
+       bitmap_replace(bmap, &exp2[1], &exp2[0], exp2_to_exp3_mask, nbits);
+       expect_eq_bitmap(bmap, exp3_1_0, nbits);
+}
+
 #define PARSE_TIME 0x1
 
 struct test_bitmap_parselist{
@@ -216,53 +304,32 @@ struct test_bitmap_parselist{
        const int flags;
 };
 
-static const unsigned long exp[] __initconst = {
-       BITMAP_FROM_U64(1),
-       BITMAP_FROM_U64(2),
-       BITMAP_FROM_U64(0x0000ffff),
-       BITMAP_FROM_U64(0xffff0000),
-       BITMAP_FROM_U64(0x55555555),
-       BITMAP_FROM_U64(0xaaaaaaaa),
-       BITMAP_FROM_U64(0x11111111),
-       BITMAP_FROM_U64(0x22222222),
-       BITMAP_FROM_U64(0xffffffff),
-       BITMAP_FROM_U64(0xfffffffe),
-       BITMAP_FROM_U64(0x3333333311111111ULL),
-       BITMAP_FROM_U64(0xffffffff77777777ULL),
-       BITMAP_FROM_U64(0),
-};
-
-static const unsigned long exp2[] __initconst = {
-       BITMAP_FROM_U64(0x3333333311111111ULL),
-       BITMAP_FROM_U64(0xffffffff77777777ULL)
-};
-
 static const struct test_bitmap_parselist parselist_tests[] __initconst = {
 #define step (sizeof(u64) / sizeof(unsigned long))
 
-       {0, "0",                        &exp[0], 8, 0},
-       {0, "1",                        &exp[1 * step], 8, 0},
-       {0, "0-15",                     &exp[2 * step], 32, 0},
-       {0, "16-31",                    &exp[3 * step], 32, 0},
-       {0, "0-31:1/2",                 &exp[4 * step], 32, 0},
-       {0, "1-31:1/2",                 &exp[5 * step], 32, 0},
-       {0, "0-31:1/4",                 &exp[6 * step], 32, 0},
-       {0, "1-31:1/4",                 &exp[7 * step], 32, 0},
-       {0, "0-31:4/4",                 &exp[8 * step], 32, 0},
-       {0, "1-31:4/4",                 &exp[9 * step], 32, 0},
-       {0, "0-31:1/4,32-63:2/4",       &exp[10 * step], 64, 0},
-       {0, "0-31:3/4,32-63:4/4",       &exp[11 * step], 64, 0},
-       {0, "  ,,  0-31:3/4  ,, 32-63:4/4  ,,  ",       &exp[11 * step], 64, 0},
+       {0, "0",                        &exp1[0], 8, 0},
+       {0, "1",                        &exp1[1 * step], 8, 0},
+       {0, "0-15",                     &exp1[2 * step], 32, 0},
+       {0, "16-31",                    &exp1[3 * step], 32, 0},
+       {0, "0-31:1/2",                 &exp1[4 * step], 32, 0},
+       {0, "1-31:1/2",                 &exp1[5 * step], 32, 0},
+       {0, "0-31:1/4",                 &exp1[6 * step], 32, 0},
+       {0, "1-31:1/4",                 &exp1[7 * step], 32, 0},
+       {0, "0-31:4/4",                 &exp1[8 * step], 32, 0},
+       {0, "1-31:4/4",                 &exp1[9 * step], 32, 0},
+       {0, "0-31:1/4,32-63:2/4",       &exp1[10 * step], 64, 0},
+       {0, "0-31:3/4,32-63:4/4",       &exp1[11 * step], 64, 0},
+       {0, "  ,,  0-31:3/4  ,, 32-63:4/4  ,,  ",       &exp1[11 * step], 64, 0},
 
        {0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4",  exp2, 128, 0},
 
        {0, "0-2047:128/256", NULL, 2048, PARSE_TIME},
 
-       {0, "",                         &exp[12 * step], 8, 0},
-       {0, "\n",                       &exp[12 * step], 8, 0},
-       {0, ",,  ,,  , ,  ,",           &exp[12 * step], 8, 0},
-       {0, " ,  ,,  , ,   ",           &exp[12 * step], 8, 0},
-       {0, " ,  ,,  , ,   \n",         &exp[12 * step], 8, 0},
+       {0, "",                         &exp1[12 * step], 8, 0},
+       {0, "\n",                       &exp1[12 * step], 8, 0},
+       {0, ",,  ,,  , ,  ,",           &exp1[12 * step], 8, 0},
+       {0, " ,  ,,  , ,   ",           &exp1[12 * step], 8, 0},
+       {0, " ,  ,,  , ,   \n",         &exp1[12 * step], 8, 0},
 
        {-EINVAL, "-1", NULL, 8, 0},
        {-EINVAL, "-0", NULL, 8, 0},
@@ -280,6 +347,8 @@ static const struct test_bitmap_parselist parselist_tests[] __initconst = {
        {-EINVAL, "a-31:10/1", NULL, 8, 0},
        {-EINVAL, "0-31:a/1", NULL, 8, 0},
        {-EINVAL, "0-\n", NULL, 8, 0},
+
+#undef step
 };
 
 static void __init __test_bitmap_parselist(int is_user)
@@ -299,7 +368,7 @@ static void __init __test_bitmap_parselist(int is_user)
 
                        set_fs(KERNEL_DS);
                        time = ktime_get();
-                       err = bitmap_parselist_user(ptest.in, len,
+                       err = bitmap_parselist_user((__force const char __user *)ptest.in, len,
                                                    bmap, ptest.nbits);
                        time = ktime_get() - time;
                        set_fs(orig_fs);
@@ -326,6 +395,8 @@ static void __init __test_bitmap_parselist(int is_user)
                if (ptest.flags & PARSE_TIME)
                        pr_err("parselist%s: %d: input is '%s' OK, Time: %llu\n",
                                        mode, i, ptest.in, time);
+
+#undef ptest
        }
 }
 
@@ -339,20 +410,20 @@ static void __init test_bitmap_parselist_user(void)
        __test_bitmap_parselist(1);
 }
 
-#define EXP_BYTES      (sizeof(exp) * 8)
+#define EXP1_IN_BITS   (sizeof(exp1) * 8)
 
 static void __init test_bitmap_arr32(void)
 {
        unsigned int nbits, next_bit;
-       u32 arr[sizeof(exp) / 4];
-       DECLARE_BITMAP(bmap2, EXP_BYTES);
+       u32 arr[EXP1_IN_BITS / 32];
+       DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
 
        memset(arr, 0xa5, sizeof(arr));
 
-       for (nbits = 0; nbits < EXP_BYTES; ++nbits) {
-               bitmap_to_arr32(arr, exp, nbits);
+       for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
+               bitmap_to_arr32(arr, exp1, nbits);
                bitmap_from_arr32(bmap2, arr, nbits);
-               expect_eq_bitmap(bmap2, exp, nbits);
+               expect_eq_bitmap(bmap2, exp1, nbits);
 
                next_bit = find_next_bit(bmap2,
                                round_up(nbits, BITS_PER_LONG), nbits);
@@ -361,7 +432,7 @@ static void __init test_bitmap_arr32(void)
                                " tail is not safely cleared: %d\n",
                                nbits, next_bit);
 
-               if (nbits < EXP_BYTES - 32)
+               if (nbits < EXP1_IN_BITS - 32)
                        expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
                                                                0xa5a5a5a5);
        }
@@ -404,15 +475,50 @@ static void noinline __init test_mem_optimisations(void)
        }
 }
 
+static const unsigned char clump_exp[] __initconst = {
+       0x01,   /* 1 bit set */
+       0x02,   /* non-edge 1 bit set */
+       0x00,   /* zero bits set */
+       0x38,   /* 3 bits set across 4-bit boundary */
+       0x38,   /* Repeated clump */
+       0x0F,   /* 4 bits set */
+       0xFF,   /* all bits set */
+       0x05,   /* non-adjacent 2 bits set */
+};
+
+static void __init test_for_each_set_clump8(void)
+{
+#define CLUMP_EXP_NUMBITS 64
+       DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS);
+       unsigned int start;
+       unsigned long clump;
+
+       /* set bitmap to test case */
+       bitmap_zero(bits, CLUMP_EXP_NUMBITS);
+       bitmap_set(bits, 0, 1);         /* 0x01 */
+       bitmap_set(bits, 9, 1);         /* 0x02 */
+       bitmap_set(bits, 27, 3);        /* 0x28 */
+       bitmap_set(bits, 35, 3);        /* 0x28 */
+       bitmap_set(bits, 40, 4);        /* 0x0F */
+       bitmap_set(bits, 48, 8);        /* 0xFF */
+       bitmap_set(bits, 56, 1);        /* 0x05 - part 1 */
+       bitmap_set(bits, 58, 1);        /* 0x05 - part 2 */
+
+       for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS)
+               expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump);
+}
+
 static void __init selftest(void)
 {
        test_zero_clear();
        test_fill_set();
        test_copy();
+       test_replace();
        test_bitmap_arr32();
        test_bitmap_parselist();
        test_bitmap_parselist_user();
        test_mem_optimisations();
+       test_for_each_set_clump8();
 }
 
 KSTM_MODULE_LOADERS(test_bitmap);
index 9742e5c..e4f706a 100644 (file)
@@ -183,6 +183,9 @@ static bool __init check_buf(void *buf, int size, bool want_ctor,
        return fail;
 }
 
+#define BULK_SIZE 100
+static void *bulk_array[BULK_SIZE];
+
 /*
  * Test kmem_cache with given parameters:
  *  want_ctor - use a constructor;
@@ -203,9 +206,24 @@ static int __init do_kmem_cache_size(size_t size, bool want_ctor,
                              want_rcu ? SLAB_TYPESAFE_BY_RCU : 0,
                              want_ctor ? test_ctor : NULL);
        for (iter = 0; iter < 10; iter++) {
+               /* Do a test of bulk allocations */
+               if (!want_rcu && !want_ctor) {
+                       int ret;
+
+                       ret = kmem_cache_alloc_bulk(c, alloc_mask, BULK_SIZE, bulk_array);
+                       if (!ret) {
+                               fail = true;
+                       } else {
+                               int i;
+                               for (i = 0; i < ret; i++)
+                                       fail |= check_buf(bulk_array[i], size, want_ctor, want_rcu, want_zero);
+                               kmem_cache_free_bulk(c, ret, bulk_array);
+                       }
+               }
+
                buf = kmem_cache_alloc(c, alloc_mask);
                /* Check that buf is zeroed, if it must be. */
-               fail = check_buf(buf, size, want_ctor, want_rcu, want_zero);
+               fail |= check_buf(buf, size, want_ctor, want_rcu, want_zero);
                fill_with_garbage_skip(buf, size, want_ctor ? CTOR_BYTES : 0);
 
                if (!want_rcu) {
index fc552d5..7b9b58a 100644 (file)
@@ -140,25 +140,21 @@ static void val_to_string(char *str, size_t size, struct type_descriptor *type,
        }
 }
 
-static DEFINE_SPINLOCK(report_lock);
-
-static void ubsan_prologue(struct source_location *location,
-                       unsigned long *flags)
+static void ubsan_prologue(struct source_location *location)
 {
        current->in_ubsan++;
-       spin_lock_irqsave(&report_lock, *flags);
 
        pr_err("========================================"
                "========================================\n");
        print_source_location("UBSAN: Undefined behaviour in", location);
 }
 
-static void ubsan_epilogue(unsigned long *flags)
+static void ubsan_epilogue(void)
 {
        dump_stack();
        pr_err("========================================"
                "========================================\n");
-       spin_unlock_irqrestore(&report_lock, *flags);
+
        current->in_ubsan--;
 }
 
@@ -167,14 +163,13 @@ static void handle_overflow(struct overflow_data *data, void *lhs,
 {
 
        struct type_descriptor *type = data->type;
-       unsigned long flags;
        char lhs_val_str[VALUE_LENGTH];
        char rhs_val_str[VALUE_LENGTH];
 
        if (suppress_report(&data->location))
                return;
 
-       ubsan_prologue(&data->location, &flags);
+       ubsan_prologue(&data->location);
 
        val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
        val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
@@ -186,7 +181,7 @@ static void handle_overflow(struct overflow_data *data, void *lhs,
                rhs_val_str,
                type->type_name);
 
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 
 void __ubsan_handle_add_overflow(struct overflow_data *data,
@@ -214,20 +209,19 @@ EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
 void __ubsan_handle_negate_overflow(struct overflow_data *data,
                                void *old_val)
 {
-       unsigned long flags;
        char old_val_str[VALUE_LENGTH];
 
        if (suppress_report(&data->location))
                return;
 
-       ubsan_prologue(&data->location, &flags);
+       ubsan_prologue(&data->location);
 
        val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
 
        pr_err("negation of %s cannot be represented in type %s:\n",
                old_val_str, data->type->type_name);
 
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
 
@@ -235,13 +229,12 @@ EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
 void __ubsan_handle_divrem_overflow(struct overflow_data *data,
                                void *lhs, void *rhs)
 {
-       unsigned long flags;
        char rhs_val_str[VALUE_LENGTH];
 
        if (suppress_report(&data->location))
                return;
 
-       ubsan_prologue(&data->location, &flags);
+       ubsan_prologue(&data->location);
 
        val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
 
@@ -251,58 +244,52 @@ void __ubsan_handle_divrem_overflow(struct overflow_data *data,
        else
                pr_err("division by zero\n");
 
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
 
 static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
 {
-       unsigned long flags;
-
        if (suppress_report(data->location))
                return;
 
-       ubsan_prologue(data->location, &flags);
+       ubsan_prologue(data->location);
 
        pr_err("%s null pointer of type %s\n",
                type_check_kinds[data->type_check_kind],
                data->type->type_name);
 
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 
 static void handle_misaligned_access(struct type_mismatch_data_common *data,
                                unsigned long ptr)
 {
-       unsigned long flags;
-
        if (suppress_report(data->location))
                return;
 
-       ubsan_prologue(data->location, &flags);
+       ubsan_prologue(data->location);
 
        pr_err("%s misaligned address %p for type %s\n",
                type_check_kinds[data->type_check_kind],
                (void *)ptr, data->type->type_name);
        pr_err("which requires %ld byte alignment\n", data->alignment);
 
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 
 static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
                                        unsigned long ptr)
 {
-       unsigned long flags;
-
        if (suppress_report(data->location))
                return;
 
-       ubsan_prologue(data->location, &flags);
+       ubsan_prologue(data->location);
        pr_err("%s address %p with insufficient space\n",
                type_check_kinds[data->type_check_kind],
                (void *) ptr);
        pr_err("for an object of type %s\n", data->type->type_name);
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 
 static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
@@ -351,25 +338,23 @@ EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
 
 void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data, void *index)
 {
-       unsigned long flags;
        char index_str[VALUE_LENGTH];
 
        if (suppress_report(&data->location))
                return;
 
-       ubsan_prologue(&data->location, &flags);
+       ubsan_prologue(&data->location);
 
        val_to_string(index_str, sizeof(index_str), data->index_type, index);
        pr_err("index %s is out of range for type %s\n", index_str,
                data->array_type->type_name);
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
 
 void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
                                        void *lhs, void *rhs)
 {
-       unsigned long flags;
        struct type_descriptor *rhs_type = data->rhs_type;
        struct type_descriptor *lhs_type = data->lhs_type;
        char rhs_str[VALUE_LENGTH];
@@ -379,7 +364,7 @@ void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
        if (suppress_report(&data->location))
                goto out;
 
-       ubsan_prologue(&data->location, &flags);
+       ubsan_prologue(&data->location);
 
        val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
        val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
@@ -402,7 +387,7 @@ void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
                        lhs_str, rhs_str,
                        lhs_type->type_name);
 
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 out:
        user_access_restore(ua_flags);
 }
@@ -411,11 +396,9 @@ EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
 
 void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
 {
-       unsigned long flags;
-
-       ubsan_prologue(&data->location, &flags);
+       ubsan_prologue(&data->location);
        pr_err("calling __builtin_unreachable()\n");
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
        panic("can't return from __builtin_unreachable()");
 }
 EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
@@ -423,19 +406,18 @@ EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
 void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
                                void *val)
 {
-       unsigned long flags;
        char val_str[VALUE_LENGTH];
 
        if (suppress_report(&data->location))
                return;
 
-       ubsan_prologue(&data->location, &flags);
+       ubsan_prologue(&data->location);
 
        val_to_string(val_str, sizeof(val_str), data->type, val);
 
        pr_err("load of value %s is not a valid value for type %s\n",
                val_str, data->type->type_name);
 
-       ubsan_epilogue(&flags);
+       ubsan_epilogue();
 }
 EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
index df3371d..2fa710b 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/bug.h>
 #include <linux/uaccess.h>
 
+#include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
 #include "kasan.h"
index 7905934..d17c7d5 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -2478,6 +2478,7 @@ int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ksm_madvise);
 
 int __ksm_enter(struct mm_struct *mm)
 {
index bc01423..c5b5f74 100644 (file)
@@ -98,14 +98,6 @@ static bool do_memsw_account(void)
        return !cgroup_subsys_on_dfl(memory_cgrp_subsys) && do_swap_account;
 }
 
-static const char *const mem_cgroup_lru_names[] = {
-       "inactive_anon",
-       "active_anon",
-       "inactive_file",
-       "active_file",
-       "unevictable",
-};
-
 #define THRESHOLDS_EVENTS_TARGET 128
 #define SOFTLIMIT_EVENTS_TARGET 1024
 
@@ -1421,7 +1413,7 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
                       PAGE_SIZE);
 
        for (i = 0; i < NR_LRU_LISTS; i++)
-               seq_buf_printf(&s, "%s %llu\n", mem_cgroup_lru_names[i],
+               seq_buf_printf(&s, "%s %llu\n", lru_list_name(i),
                               (u64)memcg_page_state(memcg, NR_LRU_BASE + i) *
                               PAGE_SIZE);
 
@@ -1434,8 +1426,10 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
 
        /* Accumulated memory events */
 
-       seq_buf_printf(&s, "pgfault %lu\n", memcg_events(memcg, PGFAULT));
-       seq_buf_printf(&s, "pgmajfault %lu\n", memcg_events(memcg, PGMAJFAULT));
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGFAULT),
+                      memcg_events(memcg, PGFAULT));
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGMAJFAULT),
+                      memcg_events(memcg, PGMAJFAULT));
 
        seq_buf_printf(&s, "workingset_refault %lu\n",
                       memcg_page_state(memcg, WORKINGSET_REFAULT));
@@ -1444,22 +1438,27 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
        seq_buf_printf(&s, "workingset_nodereclaim %lu\n",
                       memcg_page_state(memcg, WORKINGSET_NODERECLAIM));
 
-       seq_buf_printf(&s, "pgrefill %lu\n", memcg_events(memcg, PGREFILL));
+       seq_buf_printf(&s, "%s %lu\n",  vm_event_name(PGREFILL),
+                      memcg_events(memcg, PGREFILL));
        seq_buf_printf(&s, "pgscan %lu\n",
                       memcg_events(memcg, PGSCAN_KSWAPD) +
                       memcg_events(memcg, PGSCAN_DIRECT));
        seq_buf_printf(&s, "pgsteal %lu\n",
                       memcg_events(memcg, PGSTEAL_KSWAPD) +
                       memcg_events(memcg, PGSTEAL_DIRECT));
-       seq_buf_printf(&s, "pgactivate %lu\n", memcg_events(memcg, PGACTIVATE));
-       seq_buf_printf(&s, "pgdeactivate %lu\n", memcg_events(memcg, PGDEACTIVATE));
-       seq_buf_printf(&s, "pglazyfree %lu\n", memcg_events(memcg, PGLAZYFREE));
-       seq_buf_printf(&s, "pglazyfreed %lu\n", memcg_events(memcg, PGLAZYFREED));
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGACTIVATE),
+                      memcg_events(memcg, PGACTIVATE));
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGDEACTIVATE),
+                      memcg_events(memcg, PGDEACTIVATE));
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGLAZYFREE),
+                      memcg_events(memcg, PGLAZYFREE));
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGLAZYFREED),
+                      memcg_events(memcg, PGLAZYFREED));
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-       seq_buf_printf(&s, "thp_fault_alloc %lu\n",
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(THP_FAULT_ALLOC),
                       memcg_events(memcg, THP_FAULT_ALLOC));
-       seq_buf_printf(&s, "thp_collapse_alloc %lu\n",
+       seq_buf_printf(&s, "%s %lu\n", vm_event_name(THP_COLLAPSE_ALLOC),
                       memcg_events(memcg, THP_COLLAPSE_ALLOC));
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
@@ -3742,13 +3741,6 @@ static const unsigned int memcg1_events[] = {
        PGMAJFAULT,
 };
 
-static const char *const memcg1_event_names[] = {
-       "pgpgin",
-       "pgpgout",
-       "pgfault",
-       "pgmajfault",
-};
-
 static int memcg_stat_show(struct seq_file *m, void *v)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_seq(m);
@@ -3757,7 +3749,6 @@ static int memcg_stat_show(struct seq_file *m, void *v)
        unsigned int i;
 
        BUILD_BUG_ON(ARRAY_SIZE(memcg1_stat_names) != ARRAY_SIZE(memcg1_stats));
-       BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS);
 
        for (i = 0; i < ARRAY_SIZE(memcg1_stats); i++) {
                if (memcg1_stats[i] == MEMCG_SWAP && !do_memsw_account())
@@ -3768,11 +3759,11 @@ static int memcg_stat_show(struct seq_file *m, void *v)
        }
 
        for (i = 0; i < ARRAY_SIZE(memcg1_events); i++)
-               seq_printf(m, "%s %lu\n", memcg1_event_names[i],
+               seq_printf(m, "%s %lu\n", vm_event_name(memcg1_events[i]),
                           memcg_events_local(memcg, memcg1_events[i]));
 
        for (i = 0; i < NR_LRU_LISTS; i++)
-               seq_printf(m, "%s %lu\n", mem_cgroup_lru_names[i],
+               seq_printf(m, "%s %lu\n", lru_list_name(i),
                           memcg_page_state_local(memcg, NR_LRU_BASE + i) *
                           PAGE_SIZE);
 
@@ -3797,11 +3788,12 @@ static int memcg_stat_show(struct seq_file *m, void *v)
        }
 
        for (i = 0; i < ARRAY_SIZE(memcg1_events); i++)
-               seq_printf(m, "total_%s %llu\n", memcg1_event_names[i],
+               seq_printf(m, "total_%s %llu\n",
+                          vm_event_name(memcg1_events[i]),
                           (u64)memcg_events(memcg, memcg1_events[i]));
 
        for (i = 0; i < NR_LRU_LISTS; i++)
-               seq_printf(m, "total_%s %llu\n", mem_cgroup_lru_names[i],
+               seq_printf(m, "total_%s %llu\n", lru_list_name(i),
                           (u64)memcg_page_state(memcg, NR_LRU_BASE + i) *
                           PAGE_SIZE);
 
index 513c3ec..606da18 100644 (file)
@@ -672,7 +672,7 @@ struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
 
        if (pmd_devmap(pmd))
                return NULL;
-       if (is_zero_pfn(pfn))
+       if (is_huge_zero_pmd(pmd))
                return NULL;
        if (unlikely(pfn > highest_memmap_pfn))
                return NULL;
@@ -4197,19 +4197,11 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
        smp_wmb(); /* See comment in __pte_alloc */
 
        ptl = pud_lock(mm, pud);
-#ifndef __ARCH_HAS_4LEVEL_HACK
        if (!pud_present(*pud)) {
                mm_inc_nr_pmds(mm);
                pud_populate(mm, pud, new);
        } else  /* Another has populated it */
                pmd_free(mm, new);
-#else
-       if (!pgd_present(*pud)) {
-               mm_inc_nr_pmds(mm);
-               pgd_populate(mm, pud, new);
-       } else /* Another has populated it */
-               pmd_free(mm, new);
-#endif /* __ARCH_HAS_4LEVEL_HACK */
        spin_unlock(ptl);
        return 0;
 }
index 8afa188..f0ab6d4 100644 (file)
@@ -904,6 +904,18 @@ static void flush_memcg_workqueue(struct kmem_cache *s)
         * previous workitems on workqueue are processed.
         */
        flush_workqueue(memcg_kmem_cache_wq);
+
+       /*
+        * If we're racing with children kmem_cache deactivation, it might
+        * take another rcu grace period to complete their destruction.
+        * At this moment the corresponding percpu_ref_kill() call should be
+        * done, but it might take another rcu grace period to complete
+        * switching to the atomic mode.
+        * Please, note that we check without grabbing the slab_mutex. It's safe
+        * because at this moment the children list can't grow.
+        */
+       if (!list_empty(&s->memcg_params.children))
+               rcu_barrier();
 }
 #else
 static inline int shutdown_memcg_caches(struct kmem_cache *s)
index a822204..78d5337 100644 (file)
@@ -1084,7 +1084,8 @@ int fragmentation_index(struct zone *zone, unsigned int order)
 }
 #endif
 
-#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) || defined(CONFIG_NUMA)
+#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) || \
+    defined(CONFIG_NUMA) || defined(CONFIG_MEMCG)
 #ifdef CONFIG_ZONE_DMA
 #define TEXT_FOR_DMA(xx) xx "_dma",
 #else
@@ -1134,7 +1135,7 @@ const char * const vmstat_text[] = {
        "numa_other",
 #endif
 
-       /* Node-based counters */
+       /* enum node_stat_item counters */
        "nr_inactive_anon",
        "nr_active_anon",
        "nr_inactive_file",
@@ -1172,7 +1173,7 @@ const char * const vmstat_text[] = {
        "nr_dirty_threshold",
        "nr_dirty_background_threshold",
 
-#ifdef CONFIG_VM_EVENT_COUNTERS
+#if defined(CONFIG_VM_EVENT_COUNTERS) || defined(CONFIG_MEMCG)
        /* enum vm_event_item counters */
        "pgpgin",
        "pgpgout",
@@ -1291,9 +1292,9 @@ const char * const vmstat_text[] = {
        "swap_ra",
        "swap_ra_hit",
 #endif
-#endif /* CONFIG_VM_EVENTS_COUNTERS */
+#endif /* CONFIG_VM_EVENT_COUNTERS || CONFIG_MEMCG */
 };
-#endif /* CONFIG_PROC_FS || CONFIG_SYSFS || CONFIG_NUMA */
+#endif /* CONFIG_PROC_FS || CONFIG_SYSFS || CONFIG_NUMA || CONFIG_MEMCG */
 
 #if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)) || \
      defined(CONFIG_PROC_FS)
@@ -1564,10 +1565,8 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
        if (is_zone_first_populated(pgdat, zone)) {
                seq_printf(m, "\n  per-node stats");
                for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) {
-                       seq_printf(m, "\n      %-12s %lu",
-                               vmstat_text[i + NR_VM_ZONE_STAT_ITEMS +
-                               NR_VM_NUMA_STAT_ITEMS],
-                               node_page_state(pgdat, i));
+                       seq_printf(m, "\n      %-12s %lu", node_stat_name(i),
+                                  node_page_state(pgdat, i));
                }
        }
        seq_printf(m,
@@ -1600,14 +1599,13 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
        }
 
        for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
-               seq_printf(m, "\n      %-12s %lu", vmstat_text[i],
-                               zone_page_state(zone, i));
+               seq_printf(m, "\n      %-12s %lu", zone_stat_name(i),
+                          zone_page_state(zone, i));
 
 #ifdef CONFIG_NUMA
        for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
-               seq_printf(m, "\n      %-12s %lu",
-                               vmstat_text[i + NR_VM_ZONE_STAT_ITEMS],
-                               zone_numa_state_snapshot(zone, i));
+               seq_printf(m, "\n      %-12s %lu", numa_stat_name(i),
+                          zone_numa_state_snapshot(zone, i));
 #endif
 
        seq_printf(m, "\n  pagesets");
@@ -1658,31 +1656,23 @@ static const struct seq_operations zoneinfo_op = {
        .show   = zoneinfo_show,
 };
 
-enum writeback_stat_item {
-       NR_DIRTY_THRESHOLD,
-       NR_DIRTY_BG_THRESHOLD,
-       NR_VM_WRITEBACK_STAT_ITEMS,
-};
+#define NR_VMSTAT_ITEMS (NR_VM_ZONE_STAT_ITEMS + \
+                        NR_VM_NUMA_STAT_ITEMS + \
+                        NR_VM_NODE_STAT_ITEMS + \
+                        NR_VM_WRITEBACK_STAT_ITEMS + \
+                        (IS_ENABLED(CONFIG_VM_EVENT_COUNTERS) ? \
+                         NR_VM_EVENT_ITEMS : 0))
 
 static void *vmstat_start(struct seq_file *m, loff_t *pos)
 {
        unsigned long *v;
-       int i, stat_items_size;
+       int i;
 
-       if (*pos >= ARRAY_SIZE(vmstat_text))
+       if (*pos >= NR_VMSTAT_ITEMS)
                return NULL;
-       stat_items_size = NR_VM_ZONE_STAT_ITEMS * sizeof(unsigned long) +
-                         NR_VM_NUMA_STAT_ITEMS * sizeof(unsigned long) +
-                         NR_VM_NODE_STAT_ITEMS * sizeof(unsigned long) +
-                         NR_VM_WRITEBACK_STAT_ITEMS * sizeof(unsigned long);
-
-#ifdef CONFIG_VM_EVENT_COUNTERS
-       stat_items_size += sizeof(struct vm_event_state);
-#endif
 
-       BUILD_BUG_ON(stat_items_size !=
-                    ARRAY_SIZE(vmstat_text) * sizeof(unsigned long));
-       v = kmalloc(stat_items_size, GFP_KERNEL);
+       BUILD_BUG_ON(ARRAY_SIZE(vmstat_text) < NR_VMSTAT_ITEMS);
+       v = kmalloc_array(NR_VMSTAT_ITEMS, sizeof(unsigned long), GFP_KERNEL);
        m->private = v;
        if (!v)
                return ERR_PTR(-ENOMEM);
@@ -1715,7 +1705,7 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos)
 static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos)
 {
        (*pos)++;
-       if (*pos >= ARRAY_SIZE(vmstat_text))
+       if (*pos >= NR_VMSTAT_ITEMS)
                return NULL;
        return (unsigned long *)m->private + *pos;
 }
@@ -1781,7 +1771,7 @@ int vmstat_refresh(struct ctl_table *table, int write,
                val = atomic_long_read(&vm_zone_stat[i]);
                if (val < 0) {
                        pr_warn("%s: %s %ld\n",
-                               __func__, vmstat_text[i], val);
+                               __func__, zone_stat_name(i), val);
                        err = -EINVAL;
                }
        }
@@ -1790,7 +1780,7 @@ int vmstat_refresh(struct ctl_table *table, int write,
                val = atomic_long_read(&vm_numa_stat[i]);
                if (val < 0) {
                        pr_warn("%s: %s %ld\n",
-                               __func__, vmstat_text[i + NR_VM_ZONE_STAT_ITEMS], val);
+                               __func__, numa_stat_name(i), val);
                        err = -EINVAL;
                }
        }
index 2cfdfbf..bea6e43 100644 (file)
@@ -523,7 +523,7 @@ int mrp_request_join(const struct net_device *dev,
        struct mrp_attr *attr;
 
        if (sizeof(struct mrp_skb_cb) + len >
-           FIELD_SIZEOF(struct sk_buff, cb))
+           sizeof_field(struct sk_buff, cb))
                return -ENOMEM;
 
        spin_lock_bh(&app->lock);
@@ -548,7 +548,7 @@ void mrp_request_leave(const struct net_device *dev,
        struct mrp_attr *attr;
 
        if (sizeof(struct mrp_skb_cb) + len >
-           FIELD_SIZEOF(struct sk_buff, cb))
+           sizeof_field(struct sk_buff, cb))
                return;
 
        spin_lock_bh(&app->lock);
@@ -692,7 +692,7 @@ static int mrp_pdu_parse_vecattr(struct mrp_applicant *app,
         * advance to the next event in its Vector.
         */
        if (sizeof(struct mrp_skb_cb) + mrp_cb(skb)->mh->attrlen >
-           FIELD_SIZEOF(struct sk_buff, cb))
+           sizeof_field(struct sk_buff, cb))
                return -1;
        if (skb_copy_bits(skb, *offset, mrp_cb(skb)->attrvalue,
                          mrp_cb(skb)->mh->attrlen) < 0)
index 4a89177..4811ec6 100644 (file)
@@ -548,7 +548,7 @@ static void batadv_recv_handler_init(void)
        BUILD_BUG_ON(sizeof(struct batadv_tvlv_tt_change) != 12);
        BUILD_BUG_ON(sizeof(struct batadv_tvlv_roam_adv) != 8);
 
-       i = FIELD_SIZEOF(struct sk_buff, cb);
+       i = sizeof_field(struct sk_buff, cb);
        BUILD_BUG_ON(sizeof(struct batadv_skb_cb) > i);
 
        /* broadcast packet */
index 915c2d6..f79205d 100644 (file)
@@ -253,21 +253,21 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
        /* priority is allowed */
 
        if (!range_is_zero(__skb, offsetof(struct __sk_buff, priority) +
-                          FIELD_SIZEOF(struct __sk_buff, priority),
+                          sizeof_field(struct __sk_buff, priority),
                           offsetof(struct __sk_buff, cb)))
                return -EINVAL;
 
        /* cb is allowed */
 
        if (!range_is_zero(__skb, offsetof(struct __sk_buff, cb) +
-                          FIELD_SIZEOF(struct __sk_buff, cb),
+                          sizeof_field(struct __sk_buff, cb),
                           offsetof(struct __sk_buff, tstamp)))
                return -EINVAL;
 
        /* tstamp is allowed */
 
        if (!range_is_zero(__skb, offsetof(struct __sk_buff, tstamp) +
-                          FIELD_SIZEOF(struct __sk_buff, tstamp),
+                          sizeof_field(struct __sk_buff, tstamp),
                           sizeof(struct __sk_buff)))
                return -EINVAL;
 
@@ -438,7 +438,7 @@ static int verify_user_bpf_flow_keys(struct bpf_flow_keys *ctx)
        /* flags is allowed */
 
        if (!range_is_zero(ctx, offsetof(struct bpf_flow_keys, flags) +
-                          FIELD_SIZEOF(struct bpf_flow_keys, flags),
+                          sizeof_field(struct bpf_flow_keys, flags),
                           sizeof(struct bpf_flow_keys)))
                return -EINVAL;
 
index 8a8f9e5..b6fe30e 100644 (file)
@@ -312,7 +312,7 @@ static int __init br_init(void)
 {
        int err;
 
-       BUILD_BUG_ON(sizeof(struct br_input_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb));
+       BUILD_BUG_ON(sizeof(struct br_input_skb_cb) > sizeof_field(struct sk_buff, cb));
 
        err = stp_proto_register(&br_stp_proto);
        if (err < 0) {
index 434effd..fb38add 100644 (file)
@@ -245,6 +245,12 @@ static int br_set_mac_address(struct net_device *dev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
+       /* dev_set_mac_addr() can be called by a master device on bridge's
+        * NETDEV_UNREGISTER, but since it's being destroyed do nothing
+        */
+       if (dev->reg_state != NETREG_REGISTERED)
+               return -EBUSY;
+
        spin_lock_bh(&br->lock);
        if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) {
                /* Mac address will be changed in br_stp_change_bridge_id(). */
index 2d56824..a9d6c97 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/nsproxy.h>
-#include <linux/parser.h>
+#include <linux/fs_parser.h>
 #include <linux/sched.h>
 #include <linux/sched/mm.h>
 #include <linux/seq_file.h>
@@ -254,58 +254,77 @@ enum {
        Opt_mount_timeout,
        Opt_osd_idle_ttl,
        Opt_osd_request_timeout,
-       Opt_last_int,
        /* int args above */
        Opt_fsid,
        Opt_name,
        Opt_secret,
        Opt_key,
        Opt_ip,
-       Opt_last_string,
        /* string args above */
        Opt_share,
-       Opt_noshare,
        Opt_crc,
-       Opt_nocrc,
        Opt_cephx_require_signatures,
-       Opt_nocephx_require_signatures,
        Opt_cephx_sign_messages,
-       Opt_nocephx_sign_messages,
        Opt_tcp_nodelay,
-       Opt_notcp_nodelay,
        Opt_abort_on_full,
 };
 
-static match_table_t opt_tokens = {
-       {Opt_osdtimeout, "osdtimeout=%d"},
-       {Opt_osdkeepalivetimeout, "osdkeepalive=%d"},
-       {Opt_mount_timeout, "mount_timeout=%d"},
-       {Opt_osd_idle_ttl, "osd_idle_ttl=%d"},
-       {Opt_osd_request_timeout, "osd_request_timeout=%d"},
-       /* int args above */
-       {Opt_fsid, "fsid=%s"},
-       {Opt_name, "name=%s"},
-       {Opt_secret, "secret=%s"},
-       {Opt_key, "key=%s"},
-       {Opt_ip, "ip=%s"},
-       /* string args above */
-       {Opt_share, "share"},
-       {Opt_noshare, "noshare"},
-       {Opt_crc, "crc"},
-       {Opt_nocrc, "nocrc"},
-       {Opt_cephx_require_signatures, "cephx_require_signatures"},
-       {Opt_nocephx_require_signatures, "nocephx_require_signatures"},
-       {Opt_cephx_sign_messages, "cephx_sign_messages"},
-       {Opt_nocephx_sign_messages, "nocephx_sign_messages"},
-       {Opt_tcp_nodelay, "tcp_nodelay"},
-       {Opt_notcp_nodelay, "notcp_nodelay"},
-       {Opt_abort_on_full, "abort_on_full"},
-       {-1, NULL}
+static const struct fs_parameter_spec ceph_param_specs[] = {
+       fsparam_flag    ("abort_on_full",               Opt_abort_on_full),
+       fsparam_flag_no ("cephx_require_signatures",    Opt_cephx_require_signatures),
+       fsparam_flag_no ("cephx_sign_messages",         Opt_cephx_sign_messages),
+       fsparam_flag_no ("crc",                         Opt_crc),
+       fsparam_string  ("fsid",                        Opt_fsid),
+       fsparam_string  ("ip",                          Opt_ip),
+       fsparam_string  ("key",                         Opt_key),
+       fsparam_u32     ("mount_timeout",               Opt_mount_timeout),
+       fsparam_string  ("name",                        Opt_name),
+       fsparam_u32     ("osd_idle_ttl",                Opt_osd_idle_ttl),
+       fsparam_u32     ("osd_request_timeout",         Opt_osd_request_timeout),
+       fsparam_u32     ("osdkeepalive",                Opt_osdkeepalivetimeout),
+       __fsparam       (fs_param_is_s32, "osdtimeout", Opt_osdtimeout,
+                        fs_param_deprecated),
+       fsparam_string  ("secret",                      Opt_secret),
+       fsparam_flag_no ("share",                       Opt_share),
+       fsparam_flag_no ("tcp_nodelay",                 Opt_tcp_nodelay),
+       {}
+};
+
+static const struct fs_parameter_description ceph_parameters = {
+        .name           = "libceph",
+        .specs          = ceph_param_specs,
 };
 
+struct ceph_options *ceph_alloc_options(void)
+{
+       struct ceph_options *opt;
+
+       opt = kzalloc(sizeof(*opt), GFP_KERNEL);
+       if (!opt)
+               return NULL;
+
+       opt->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*opt->mon_addr),
+                               GFP_KERNEL);
+       if (!opt->mon_addr) {
+               kfree(opt);
+               return NULL;
+       }
+
+       opt->flags = CEPH_OPT_DEFAULT;
+       opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
+       opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT;
+       opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;
+       opt->osd_request_timeout = CEPH_OSD_REQUEST_TIMEOUT_DEFAULT;
+       return opt;
+}
+EXPORT_SYMBOL(ceph_alloc_options);
+
 void ceph_destroy_options(struct ceph_options *opt)
 {
        dout("destroy_options %p\n", opt);
+       if (!opt)
+               return;
+
        kfree(opt->name);
        if (opt->key) {
                ceph_crypto_key_destroy(opt->key);
@@ -317,7 +336,9 @@ void ceph_destroy_options(struct ceph_options *opt)
 EXPORT_SYMBOL(ceph_destroy_options);
 
 /* get secret from key store */
-static int get_secret(struct ceph_crypto_key *dst, const char *name) {
+static int get_secret(struct ceph_crypto_key *dst, const char *name,
+                     struct fs_context *fc)
+{
        struct key *ukey;
        int key_err;
        int err = 0;
@@ -330,20 +351,20 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) {
                key_err = PTR_ERR(ukey);
                switch (key_err) {
                case -ENOKEY:
-                       pr_warn("ceph: Mount failed due to key not found: %s\n",
-                               name);
+                       errorf(fc, "libceph: Failed due to key not found: %s",
+                              name);
                        break;
                case -EKEYEXPIRED:
-                       pr_warn("ceph: Mount failed due to expired key: %s\n",
-                               name);
+                       errorf(fc, "libceph: Failed due to expired key: %s",
+                              name);
                        break;
                case -EKEYREVOKED:
-                       pr_warn("ceph: Mount failed due to revoked key: %s\n",
-                               name);
+                       errorf(fc, "libceph: Failed due to revoked key: %s",
+                              name);
                        break;
                default:
-                       pr_warn("ceph: Mount failed due to unknown key error %d: %s\n",
-                               key_err, name);
+                       errorf(fc, "libceph: Failed due to key error %d: %s",
+                              key_err, name);
                }
                err = -EPERM;
                goto out;
@@ -361,217 +382,157 @@ out:
        return err;
 }
 
-struct ceph_options *
-ceph_parse_options(char *options, const char *dev_name,
-                       const char *dev_name_end,
-                       int (*parse_extra_token)(char *c, void *private),
-                       void *private)
+int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
+                      struct fs_context *fc)
 {
-       struct ceph_options *opt;
-       const char *c;
-       int err = -ENOMEM;
-       substring_t argstr[MAX_OPT_ARGS];
-
-       opt = kzalloc(sizeof(*opt), GFP_KERNEL);
-       if (!opt)
-               return ERR_PTR(-ENOMEM);
-       opt->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*opt->mon_addr),
-                               GFP_KERNEL);
-       if (!opt->mon_addr)
-               goto out;
-
-       dout("parse_options %p options '%s' dev_name '%s'\n", opt, options,
-            dev_name);
-
-       /* start with defaults */
-       opt->flags = CEPH_OPT_DEFAULT;
-       opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
-       opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT;
-       opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;
-       opt->osd_request_timeout = CEPH_OSD_REQUEST_TIMEOUT_DEFAULT;
+       int ret;
 
-       /* get mon ip(s) */
        /* ip1[:port1][,ip2[:port2]...] */
-       err = ceph_parse_ips(dev_name, dev_name_end, opt->mon_addr,
-                            CEPH_MAX_MON, &opt->num_mon);
-       if (err < 0)
-               goto out;
+       ret = ceph_parse_ips(buf, buf + len, opt->mon_addr, CEPH_MAX_MON,
+                            &opt->num_mon);
+       if (ret) {
+               errorf(fc, "libceph: Failed to parse monitor IPs: %d", ret);
+               return ret;
+       }
 
-       /* parse mount options */
-       while ((c = strsep(&options, ",")) != NULL) {
-               int token, intval;
-               if (!*c)
-                       continue;
-               err = -EINVAL;
-               token = match_token((char *)c, opt_tokens, argstr);
-               if (token < 0 && parse_extra_token) {
-                       /* extra? */
-                       err = parse_extra_token((char *)c, private);
-                       if (err < 0) {
-                               pr_err("bad option at '%s'\n", c);
-                               goto out;
-                       }
-                       continue;
-               }
-               if (token < Opt_last_int) {
-                       err = match_int(&argstr[0], &intval);
-                       if (err < 0) {
-                               pr_err("bad option arg (not int) at '%s'\n", c);
-                               goto out;
-                       }
-                       dout("got int token %d val %d\n", token, intval);
-               } else if (token > Opt_last_int && token < Opt_last_string) {
-                       dout("got string token %d val %s\n", token,
-                            argstr[0].from);
-               } else {
-                       dout("got token %d\n", token);
+       return 0;
+}
+EXPORT_SYMBOL(ceph_parse_mon_ips);
+
+int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
+                    struct fs_context *fc)
+{
+       struct fs_parse_result result;
+       int token, err;
+
+       token = fs_parse(fc, &ceph_parameters, param, &result);
+       dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
+       if (token < 0)
+               return token;
+
+       switch (token) {
+       case Opt_ip:
+               err = ceph_parse_ips(param->string,
+                                    param->string + param->size,
+                                    &opt->my_addr,
+                                    1, NULL);
+               if (err) {
+                       errorf(fc, "libceph: Failed to parse ip: %d", err);
+                       return err;
                }
-               switch (token) {
-               case Opt_ip:
-                       err = ceph_parse_ips(argstr[0].from,
-                                            argstr[0].to,
-                                            &opt->my_addr,
-                                            1, NULL);
-                       if (err < 0)
-                               goto out;
-                       opt->flags |= CEPH_OPT_MYIP;
-                       break;
+               opt->flags |= CEPH_OPT_MYIP;
+               break;
 
-               case Opt_fsid:
-                       err = parse_fsid(argstr[0].from, &opt->fsid);
-                       if (err == 0)
-                               opt->flags |= CEPH_OPT_FSID;
-                       break;
-               case Opt_name:
-                       kfree(opt->name);
-                       opt->name = kstrndup(argstr[0].from,
-                                             argstr[0].to-argstr[0].from,
-                                             GFP_KERNEL);
-                       if (!opt->name) {
-                               err = -ENOMEM;
-                               goto out;
-                       }
-                       break;
-               case Opt_secret:
-                       ceph_crypto_key_destroy(opt->key);
-                       kfree(opt->key);
-
-                       opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
-                       if (!opt->key) {
-                               err = -ENOMEM;
-                               goto out;
-                       }
-                       err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
-                       if (err < 0)
-                               goto out;
-                       break;
-               case Opt_key:
-                       ceph_crypto_key_destroy(opt->key);
-                       kfree(opt->key);
-
-                       opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
-                       if (!opt->key) {
-                               err = -ENOMEM;
-                               goto out;
-                       }
-                       err = get_secret(opt->key, argstr[0].from);
-                       if (err < 0)
-                               goto out;
-                       break;
+       case Opt_fsid:
+               err = parse_fsid(param->string, &opt->fsid);
+               if (err) {
+                       errorf(fc, "libceph: Failed to parse fsid: %d", err);
+                       return err;
+               }
+               opt->flags |= CEPH_OPT_FSID;
+               break;
+       case Opt_name:
+               kfree(opt->name);
+               opt->name = param->string;
+               param->string = NULL;
+               break;
+       case Opt_secret:
+               ceph_crypto_key_destroy(opt->key);
+               kfree(opt->key);
 
-                       /* misc */
-               case Opt_osdtimeout:
-                       pr_warn("ignoring deprecated osdtimeout option\n");
-                       break;
-               case Opt_osdkeepalivetimeout:
-                       /* 0 isn't well defined right now, reject it */
-                       if (intval < 1 || intval > INT_MAX / 1000) {
-                               pr_err("osdkeepalive out of range\n");
-                               err = -EINVAL;
-                               goto out;
-                       }
-                       opt->osd_keepalive_timeout =
-                                       msecs_to_jiffies(intval * 1000);
-                       break;
-               case Opt_osd_idle_ttl:
-                       /* 0 isn't well defined right now, reject it */
-                       if (intval < 1 || intval > INT_MAX / 1000) {
-                               pr_err("osd_idle_ttl out of range\n");
-                               err = -EINVAL;
-                               goto out;
-                       }
-                       opt->osd_idle_ttl = msecs_to_jiffies(intval * 1000);
-                       break;
-               case Opt_mount_timeout:
-                       /* 0 is "wait forever" (i.e. infinite timeout) */
-                       if (intval < 0 || intval > INT_MAX / 1000) {
-                               pr_err("mount_timeout out of range\n");
-                               err = -EINVAL;
-                               goto out;
-                       }
-                       opt->mount_timeout = msecs_to_jiffies(intval * 1000);
-                       break;
-               case Opt_osd_request_timeout:
-                       /* 0 is "wait forever" (i.e. infinite timeout) */
-                       if (intval < 0 || intval > INT_MAX / 1000) {
-                               pr_err("osd_request_timeout out of range\n");
-                               err = -EINVAL;
-                               goto out;
-                       }
-                       opt->osd_request_timeout = msecs_to_jiffies(intval * 1000);
-                       break;
+               opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+               if (!opt->key)
+                       return -ENOMEM;
+               err = ceph_crypto_key_unarmor(opt->key, param->string);
+               if (err) {
+                       errorf(fc, "libceph: Failed to parse secret: %d", err);
+                       return err;
+               }
+               break;
+       case Opt_key:
+               ceph_crypto_key_destroy(opt->key);
+               kfree(opt->key);
 
-               case Opt_share:
+               opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+               if (!opt->key)
+                       return -ENOMEM;
+               return get_secret(opt->key, param->string, fc);
+
+       case Opt_osdtimeout:
+               warnf(fc, "libceph: Ignoring osdtimeout");
+               break;
+       case Opt_osdkeepalivetimeout:
+               /* 0 isn't well defined right now, reject it */
+               if (result.uint_32 < 1 || result.uint_32 > INT_MAX / 1000)
+                       goto out_of_range;
+               opt->osd_keepalive_timeout =
+                   msecs_to_jiffies(result.uint_32 * 1000);
+               break;
+       case Opt_osd_idle_ttl:
+               /* 0 isn't well defined right now, reject it */
+               if (result.uint_32 < 1 || result.uint_32 > INT_MAX / 1000)
+                       goto out_of_range;
+               opt->osd_idle_ttl = msecs_to_jiffies(result.uint_32 * 1000);
+               break;
+       case Opt_mount_timeout:
+               /* 0 is "wait forever" (i.e. infinite timeout) */
+               if (result.uint_32 > INT_MAX / 1000)
+                       goto out_of_range;
+               opt->mount_timeout = msecs_to_jiffies(result.uint_32 * 1000);
+               break;
+       case Opt_osd_request_timeout:
+               /* 0 is "wait forever" (i.e. infinite timeout) */
+               if (result.uint_32 > INT_MAX / 1000)
+                       goto out_of_range;
+               opt->osd_request_timeout =
+                   msecs_to_jiffies(result.uint_32 * 1000);
+               break;
+
+       case Opt_share:
+               if (!result.negated)
                        opt->flags &= ~CEPH_OPT_NOSHARE;
-                       break;
-               case Opt_noshare:
+               else
                        opt->flags |= CEPH_OPT_NOSHARE;
-                       break;
-
-               case Opt_crc:
+               break;
+       case Opt_crc:
+               if (!result.negated)
                        opt->flags &= ~CEPH_OPT_NOCRC;
-                       break;
-               case Opt_nocrc:
+               else
                        opt->flags |= CEPH_OPT_NOCRC;
-                       break;
-
-               case Opt_cephx_require_signatures:
+               break;
+       case Opt_cephx_require_signatures:
+               if (!result.negated)
                        opt->flags &= ~CEPH_OPT_NOMSGAUTH;
-                       break;
-               case Opt_nocephx_require_signatures:
+               else
                        opt->flags |= CEPH_OPT_NOMSGAUTH;
-                       break;
-               case Opt_cephx_sign_messages:
+               break;
+       case Opt_cephx_sign_messages:
+               if (!result.negated)
                        opt->flags &= ~CEPH_OPT_NOMSGSIGN;
-                       break;
-               case Opt_nocephx_sign_messages:
+               else
                        opt->flags |= CEPH_OPT_NOMSGSIGN;
-                       break;
-
-               case Opt_tcp_nodelay:
+               break;
+       case Opt_tcp_nodelay:
+               if (!result.negated)
                        opt->flags |= CEPH_OPT_TCP_NODELAY;
-                       break;
-               case Opt_notcp_nodelay:
+               else
                        opt->flags &= ~CEPH_OPT_TCP_NODELAY;
-                       break;
+               break;
 
-               case Opt_abort_on_full:
-                       opt->flags |= CEPH_OPT_ABORT_ON_FULL;
-                       break;
+       case Opt_abort_on_full:
+               opt->flags |= CEPH_OPT_ABORT_ON_FULL;
+               break;
 
-               default:
-                       BUG_ON(token);
-               }
+       default:
+               BUG();
        }
 
-       /* success */
-       return opt;
+       return 0;
 
-out:
-       ceph_destroy_options(opt);
-       return ERR_PTR(err);
+out_of_range:
+       return invalf(fc, "libceph: %s out of range", param->key);
 }
-EXPORT_SYMBOL(ceph_parse_options);
+EXPORT_SYMBOL(ceph_parse_param);
 
 int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
                              bool show_all)
index e4cb3db..5b4bd82 100644 (file)
@@ -2004,10 +2004,8 @@ int ceph_parse_ips(const char *c, const char *end,
        return 0;
 
 bad:
-       pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c);
        return ret;
 }
-EXPORT_SYMBOL(ceph_parse_ips);
 
 static int process_banner(struct ceph_connection *con)
 {
index 7256c40..9d9e4e4 100644 (file)
@@ -1233,9 +1233,6 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
        struct ceph_mon_client *monc = con->private;
        int type = le16_to_cpu(msg->hdr.type);
 
-       if (!monc)
-               return;
-
        switch (type) {
        case CEPH_MSG_AUTH_REPLY:
                handle_auth_reply(monc, msg);
index 46580b2..0ad39c8 100644 (file)
@@ -8188,7 +8188,8 @@ int __dev_set_mtu(struct net_device *dev, int new_mtu)
        if (ops->ndo_change_mtu)
                return ops->ndo_change_mtu(dev, new_mtu);
 
-       dev->mtu = new_mtu;
+       /* Pairs with all the lockless reads of dev->mtu in the stack */
+       WRITE_ONCE(dev->mtu, new_mtu);
        return 0;
 }
 EXPORT_SYMBOL(__dev_set_mtu);
@@ -9246,7 +9247,7 @@ int register_netdevice(struct net_device *dev)
                if (ret) {
                        if (ret > 0)
                                ret = -EIO;
-                       goto out;
+                       goto err_free_name;
                }
        }
 
@@ -9361,12 +9362,12 @@ out:
        return ret;
 
 err_uninit:
-       if (dev->name_node)
-               netdev_name_node_free(dev->name_node);
        if (dev->netdev_ops->ndo_uninit)
                dev->netdev_ops->ndo_uninit(dev);
        if (dev->priv_destructor)
                dev->priv_destructor(dev);
+err_free_name:
+       netdev_name_node_free(dev->name_node);
        goto out;
 }
 EXPORT_SYMBOL(register_netdevice);
@@ -10164,7 +10165,7 @@ static struct hlist_head * __net_init netdev_create_hash(void)
 static int __net_init netdev_init(struct net *net)
 {
        BUILD_BUG_ON(GRO_HASH_BUCKETS >
-                    8 * FIELD_SIZEOF(struct napi_struct, gro_bitmask));
+                    8 * sizeof_field(struct napi_struct, gro_bitmask));
 
        if (net != &init_net)
                INIT_LIST_HEAD(&net->dev_base_head);
index f1e703e..c19dd09 100644 (file)
@@ -274,7 +274,7 @@ static u32 convert_skb_access(int skb_field, int dst_reg, int src_reg,
 
        switch (skb_field) {
        case SKF_AD_MARK:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sk_buff, mark) != 4);
 
                *insn++ = BPF_LDX_MEM(BPF_W, dst_reg, src_reg,
                                      offsetof(struct sk_buff, mark));
@@ -289,14 +289,14 @@ static u32 convert_skb_access(int skb_field, int dst_reg, int src_reg,
                break;
 
        case SKF_AD_QUEUE:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sk_buff, queue_mapping) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_H, dst_reg, src_reg,
                                      offsetof(struct sk_buff, queue_mapping));
                break;
 
        case SKF_AD_VLAN_TAG:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sk_buff, vlan_tci) != 2);
 
                /* dst_reg = *(u16 *) (src_reg + offsetof(vlan_tci)) */
                *insn++ = BPF_LDX_MEM(BPF_H, dst_reg, src_reg,
@@ -322,7 +322,7 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
 
        switch (fp->k) {
        case SKF_AD_OFF + SKF_AD_PROTOCOL:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sk_buff, protocol) != 2);
 
                /* A = *(u16 *) (CTX + offsetof(protocol)) */
                *insn++ = BPF_LDX_MEM(BPF_H, BPF_REG_A, BPF_REG_CTX,
@@ -338,8 +338,8 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
 
        case SKF_AD_OFF + SKF_AD_IFINDEX:
        case SKF_AD_OFF + SKF_AD_HATYPE:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4);
-               BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, type) != 2);
+               BUILD_BUG_ON(sizeof_field(struct net_device, ifindex) != 4);
+               BUILD_BUG_ON(sizeof_field(struct net_device, type) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, dev),
                                      BPF_REG_TMP, BPF_REG_CTX,
@@ -361,7 +361,7 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
                break;
 
        case SKF_AD_OFF + SKF_AD_RXHASH:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sk_buff, hash) != 4);
 
                *insn = BPF_LDX_MEM(BPF_W, BPF_REG_A, BPF_REG_CTX,
                                    offsetof(struct sk_buff, hash));
@@ -385,7 +385,7 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
                break;
 
        case SKF_AD_OFF + SKF_AD_VLAN_TPID:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_proto) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sk_buff, vlan_proto) != 2);
 
                /* A = *(u16 *) (CTX + offsetof(vlan_proto)) */
                *insn++ = BPF_LDX_MEM(BPF_H, BPF_REG_A, BPF_REG_CTX,
@@ -5589,8 +5589,8 @@ u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
 
 #define BPF_TCP_SOCK_GET_COMMON(FIELD)                                 \
        do {                                                            \
-               BUILD_BUG_ON(FIELD_SIZEOF(struct tcp_sock, FIELD) >     \
-                            FIELD_SIZEOF(struct bpf_tcp_sock, FIELD)); \
+               BUILD_BUG_ON(sizeof_field(struct tcp_sock, FIELD) >     \
+                            sizeof_field(struct bpf_tcp_sock, FIELD)); \
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct tcp_sock, FIELD),\
                                      si->dst_reg, si->src_reg,         \
                                      offsetof(struct tcp_sock, FIELD)); \
@@ -5598,9 +5598,9 @@ u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
 
 #define BPF_INET_SOCK_GET_COMMON(FIELD)                                        \
        do {                                                            \
-               BUILD_BUG_ON(FIELD_SIZEOF(struct inet_connection_sock,  \
+               BUILD_BUG_ON(sizeof_field(struct inet_connection_sock,  \
                                          FIELD) >                      \
-                            FIELD_SIZEOF(struct bpf_tcp_sock, FIELD)); \
+                            sizeof_field(struct bpf_tcp_sock, FIELD)); \
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(                 \
                                        struct inet_connection_sock,    \
                                        FIELD),                         \
@@ -5615,7 +5615,7 @@ u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
 
        switch (si->off) {
        case offsetof(struct bpf_tcp_sock, rtt_min):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct tcp_sock, rtt_min) !=
+               BUILD_BUG_ON(sizeof_field(struct tcp_sock, rtt_min) !=
                             sizeof(struct minmax));
                BUILD_BUG_ON(sizeof(struct minmax) <
                             sizeof(struct minmax_sample));
@@ -5780,8 +5780,8 @@ u32 bpf_xdp_sock_convert_ctx_access(enum bpf_access_type type,
 
 #define BPF_XDP_SOCK_GET(FIELD)                                                \
        do {                                                            \
-               BUILD_BUG_ON(FIELD_SIZEOF(struct xdp_sock, FIELD) >     \
-                            FIELD_SIZEOF(struct bpf_xdp_sock, FIELD)); \
+               BUILD_BUG_ON(sizeof_field(struct xdp_sock, FIELD) >     \
+                            sizeof_field(struct bpf_xdp_sock, FIELD)); \
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_sock, FIELD),\
                                      si->dst_reg, si->src_reg,         \
                                      offsetof(struct xdp_sock, FIELD)); \
@@ -7344,7 +7344,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
 
        case offsetof(struct __sk_buff, cb[0]) ...
             offsetofend(struct __sk_buff, cb[4]) - 1:
-               BUILD_BUG_ON(FIELD_SIZEOF(struct qdisc_skb_cb, data) < 20);
+               BUILD_BUG_ON(sizeof_field(struct qdisc_skb_cb, data) < 20);
                BUILD_BUG_ON((offsetof(struct sk_buff, cb) +
                              offsetof(struct qdisc_skb_cb, data)) %
                             sizeof(__u64));
@@ -7363,7 +7363,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct __sk_buff, tc_classid):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct qdisc_skb_cb, tc_classid) != 2);
+               BUILD_BUG_ON(sizeof_field(struct qdisc_skb_cb, tc_classid) != 2);
 
                off  = si->off;
                off -= offsetof(struct __sk_buff, tc_classid);
@@ -7434,7 +7434,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
 #endif
                break;
        case offsetof(struct __sk_buff, family):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_family) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_family) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk),
                                      si->dst_reg, si->src_reg,
@@ -7445,7 +7445,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                                                     2, target_size));
                break;
        case offsetof(struct __sk_buff, remote_ip4):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_daddr) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_daddr) != 4);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk),
                                      si->dst_reg, si->src_reg,
@@ -7456,7 +7456,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                                                     4, target_size));
                break;
        case offsetof(struct __sk_buff, local_ip4):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_rcv_saddr) != 4);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk),
@@ -7470,7 +7470,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
        case offsetof(struct __sk_buff, remote_ip6[0]) ...
             offsetof(struct __sk_buff, remote_ip6[3]):
 #if IS_ENABLED(CONFIG_IPV6)
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_v6_daddr.s6_addr32[0]) != 4);
 
                off = si->off;
@@ -7490,7 +7490,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
        case offsetof(struct __sk_buff, local_ip6[0]) ...
             offsetof(struct __sk_buff, local_ip6[3]):
 #if IS_ENABLED(CONFIG_IPV6)
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_v6_rcv_saddr.s6_addr32[0]) != 4);
 
                off = si->off;
@@ -7509,7 +7509,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct __sk_buff, remote_port):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_dport) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_dport) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk),
                                      si->dst_reg, si->src_reg,
@@ -7524,7 +7524,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct __sk_buff, local_port):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_num) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_num) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk),
                                      si->dst_reg, si->src_reg,
@@ -7535,7 +7535,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct __sk_buff, tstamp):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, tstamp) != 8);
+               BUILD_BUG_ON(sizeof_field(struct sk_buff, tstamp) != 8);
 
                if (type == BPF_WRITE)
                        *insn++ = BPF_STX_MEM(BPF_DW,
@@ -7573,7 +7573,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                                                     target_size));
                break;
        case offsetof(struct __sk_buff, wire_len):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct qdisc_skb_cb, pkt_len) != 4);
+               BUILD_BUG_ON(sizeof_field(struct qdisc_skb_cb, pkt_len) != 4);
 
                off = si->off;
                off -= offsetof(struct __sk_buff, wire_len);
@@ -7603,7 +7603,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
 
        switch (si->off) {
        case offsetof(struct bpf_sock, bound_dev_if):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_bound_dev_if) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sock, sk_bound_dev_if) != 4);
 
                if (type == BPF_WRITE)
                        *insn++ = BPF_STX_MEM(BPF_W, si->dst_reg, si->src_reg,
@@ -7614,7 +7614,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock, mark):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_mark) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sock, sk_mark) != 4);
 
                if (type == BPF_WRITE)
                        *insn++ = BPF_STX_MEM(BPF_W, si->dst_reg, si->src_reg,
@@ -7625,7 +7625,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock, priority):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_priority) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sock, sk_priority) != 4);
 
                if (type == BPF_WRITE)
                        *insn++ = BPF_STX_MEM(BPF_W, si->dst_reg, si->src_reg,
@@ -7641,7 +7641,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                        si->dst_reg, si->src_reg,
                        bpf_target_off(struct sock_common,
                                       skc_family,
-                                      FIELD_SIZEOF(struct sock_common,
+                                      sizeof_field(struct sock_common,
                                                    skc_family),
                                       target_size));
                break;
@@ -7668,7 +7668,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                *insn++ = BPF_LDX_MEM(
                        BPF_SIZE(si->code), si->dst_reg, si->src_reg,
                        bpf_target_off(struct sock_common, skc_rcv_saddr,
-                                      FIELD_SIZEOF(struct sock_common,
+                                      sizeof_field(struct sock_common,
                                                    skc_rcv_saddr),
                                       target_size));
                break;
@@ -7677,7 +7677,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                *insn++ = BPF_LDX_MEM(
                        BPF_SIZE(si->code), si->dst_reg, si->src_reg,
                        bpf_target_off(struct sock_common, skc_daddr,
-                                      FIELD_SIZEOF(struct sock_common,
+                                      sizeof_field(struct sock_common,
                                                    skc_daddr),
                                       target_size));
                break;
@@ -7691,7 +7691,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                        bpf_target_off(
                                struct sock_common,
                                skc_v6_rcv_saddr.s6_addr32[0],
-                               FIELD_SIZEOF(struct sock_common,
+                               sizeof_field(struct sock_common,
                                             skc_v6_rcv_saddr.s6_addr32[0]),
                                target_size) + off);
 #else
@@ -7708,7 +7708,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                        BPF_SIZE(si->code), si->dst_reg, si->src_reg,
                        bpf_target_off(struct sock_common,
                                       skc_v6_daddr.s6_addr32[0],
-                                      FIELD_SIZEOF(struct sock_common,
+                                      sizeof_field(struct sock_common,
                                                    skc_v6_daddr.s6_addr32[0]),
                                       target_size) + off);
 #else
@@ -7722,7 +7722,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                        BPF_FIELD_SIZEOF(struct sock_common, skc_num),
                        si->dst_reg, si->src_reg,
                        bpf_target_off(struct sock_common, skc_num,
-                                      FIELD_SIZEOF(struct sock_common,
+                                      sizeof_field(struct sock_common,
                                                    skc_num),
                                       target_size));
                break;
@@ -7732,7 +7732,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                        BPF_FIELD_SIZEOF(struct sock_common, skc_dport),
                        si->dst_reg, si->src_reg,
                        bpf_target_off(struct sock_common, skc_dport,
-                                      FIELD_SIZEOF(struct sock_common,
+                                      sizeof_field(struct sock_common,
                                                    skc_dport),
                                       target_size));
                break;
@@ -7742,7 +7742,7 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
                        BPF_FIELD_SIZEOF(struct sock_common, skc_state),
                        si->dst_reg, si->src_reg,
                        bpf_target_off(struct sock_common, skc_state,
-                                      FIELD_SIZEOF(struct sock_common,
+                                      sizeof_field(struct sock_common,
                                                    skc_state),
                                       target_size));
                break;
@@ -7837,7 +7837,7 @@ static u32 xdp_convert_ctx_access(enum bpf_access_type type,
                                      si->src_reg, offsetof(S, F));            \
                *insn++ = BPF_LDX_MEM(                                         \
                        SIZE, si->dst_reg, si->dst_reg,                        \
-                       bpf_target_off(NS, NF, FIELD_SIZEOF(NS, NF),           \
+                       bpf_target_off(NS, NF, sizeof_field(NS, NF),           \
                                       target_size)                            \
                                + OFF);                                        \
        } while (0)
@@ -7868,7 +7868,7 @@ static u32 xdp_convert_ctx_access(enum bpf_access_type type,
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(S, F), tmp_reg,         \
                                      si->dst_reg, offsetof(S, F));            \
                *insn++ = BPF_STX_MEM(SIZE, tmp_reg, si->src_reg,              \
-                       bpf_target_off(NS, NF, FIELD_SIZEOF(NS, NF),           \
+                       bpf_target_off(NS, NF, sizeof_field(NS, NF),           \
                                       target_size)                            \
                                + OFF);                                        \
                *insn++ = BPF_LDX_MEM(BPF_DW, tmp_reg, si->dst_reg,            \
@@ -7930,8 +7930,8 @@ static u32 sock_addr_convert_ctx_access(enum bpf_access_type type,
                 */
                BUILD_BUG_ON(offsetof(struct sockaddr_in, sin_port) !=
                             offsetof(struct sockaddr_in6, sin6_port));
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sockaddr_in, sin_port) !=
-                            FIELD_SIZEOF(struct sockaddr_in6, sin6_port));
+               BUILD_BUG_ON(sizeof_field(struct sockaddr_in, sin_port) !=
+                            sizeof_field(struct sockaddr_in6, sin6_port));
                SOCK_ADDR_LOAD_OR_STORE_NESTED_FIELD(struct bpf_sock_addr_kern,
                                                     struct sockaddr_in6, uaddr,
                                                     sin6_port, tmp_reg);
@@ -7997,8 +7997,8 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
 /* Helper macro for adding read access to tcp_sock or sock fields. */
 #define SOCK_OPS_GET_FIELD(BPF_FIELD, OBJ_FIELD, OBJ)                        \
        do {                                                                  \
-               BUILD_BUG_ON(FIELD_SIZEOF(OBJ, OBJ_FIELD) >                   \
-                            FIELD_SIZEOF(struct bpf_sock_ops, BPF_FIELD));   \
+               BUILD_BUG_ON(sizeof_field(OBJ, OBJ_FIELD) >                   \
+                            sizeof_field(struct bpf_sock_ops, BPF_FIELD));   \
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(                       \
                                                struct bpf_sock_ops_kern,     \
                                                is_fullsock),                 \
@@ -8031,8 +8031,8 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
 #define SOCK_OPS_SET_FIELD(BPF_FIELD, OBJ_FIELD, OBJ)                        \
        do {                                                                  \
                int reg = BPF_REG_9;                                          \
-               BUILD_BUG_ON(FIELD_SIZEOF(OBJ, OBJ_FIELD) >                   \
-                            FIELD_SIZEOF(struct bpf_sock_ops, BPF_FIELD));   \
+               BUILD_BUG_ON(sizeof_field(OBJ, OBJ_FIELD) >                   \
+                            sizeof_field(struct bpf_sock_ops, BPF_FIELD));   \
                if (si->dst_reg == reg || si->src_reg == reg)                 \
                        reg--;                                                \
                if (si->dst_reg == reg || si->src_reg == reg)                 \
@@ -8073,12 +8073,12 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
        switch (si->off) {
        case offsetof(struct bpf_sock_ops, op) ...
             offsetof(struct bpf_sock_ops, replylong[3]):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct bpf_sock_ops, op) !=
-                            FIELD_SIZEOF(struct bpf_sock_ops_kern, op));
-               BUILD_BUG_ON(FIELD_SIZEOF(struct bpf_sock_ops, reply) !=
-                            FIELD_SIZEOF(struct bpf_sock_ops_kern, reply));
-               BUILD_BUG_ON(FIELD_SIZEOF(struct bpf_sock_ops, replylong) !=
-                            FIELD_SIZEOF(struct bpf_sock_ops_kern, replylong));
+               BUILD_BUG_ON(sizeof_field(struct bpf_sock_ops, op) !=
+                            sizeof_field(struct bpf_sock_ops_kern, op));
+               BUILD_BUG_ON(sizeof_field(struct bpf_sock_ops, reply) !=
+                            sizeof_field(struct bpf_sock_ops_kern, reply));
+               BUILD_BUG_ON(sizeof_field(struct bpf_sock_ops, replylong) !=
+                            sizeof_field(struct bpf_sock_ops_kern, replylong));
                off = si->off;
                off -= offsetof(struct bpf_sock_ops, op);
                off += offsetof(struct bpf_sock_ops_kern, op);
@@ -8091,7 +8091,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock_ops, family):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_family) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_family) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                              struct bpf_sock_ops_kern, sk),
@@ -8102,7 +8102,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock_ops, remote_ip4):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_daddr) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_daddr) != 4);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                                struct bpf_sock_ops_kern, sk),
@@ -8113,7 +8113,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock_ops, local_ip4):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_rcv_saddr) != 4);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
@@ -8128,7 +8128,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
        case offsetof(struct bpf_sock_ops, remote_ip6[0]) ...
             offsetof(struct bpf_sock_ops, remote_ip6[3]):
 #if IS_ENABLED(CONFIG_IPV6)
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_v6_daddr.s6_addr32[0]) != 4);
 
                off = si->off;
@@ -8149,7 +8149,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
        case offsetof(struct bpf_sock_ops, local_ip6[0]) ...
             offsetof(struct bpf_sock_ops, local_ip6[3]):
 #if IS_ENABLED(CONFIG_IPV6)
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_v6_rcv_saddr.s6_addr32[0]) != 4);
 
                off = si->off;
@@ -8168,7 +8168,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock_ops, remote_port):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_dport) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_dport) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                                struct bpf_sock_ops_kern, sk),
@@ -8182,7 +8182,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock_ops, local_port):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_num) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_num) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                                struct bpf_sock_ops_kern, sk),
@@ -8202,7 +8202,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock_ops, state):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_state) != 1);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_state) != 1);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                                struct bpf_sock_ops_kern, sk),
@@ -8213,7 +8213,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct bpf_sock_ops, rtt_min):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct tcp_sock, rtt_min) !=
+               BUILD_BUG_ON(sizeof_field(struct tcp_sock, rtt_min) !=
                             sizeof(struct minmax));
                BUILD_BUG_ON(sizeof(struct minmax) <
                             sizeof(struct minmax_sample));
@@ -8224,7 +8224,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                                      offsetof(struct bpf_sock_ops_kern, sk));
                *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg,
                                      offsetof(struct tcp_sock, rtt_min) +
-                                     FIELD_SIZEOF(struct minmax_sample, t));
+                                     sizeof_field(struct minmax_sample, t));
                break;
 
        case offsetof(struct bpf_sock_ops, bpf_sock_ops_cb_flags):
@@ -8366,7 +8366,7 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
                                      offsetof(struct sk_msg, data_end));
                break;
        case offsetof(struct sk_msg_md, family):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_family) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_family) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                              struct sk_msg, sk),
@@ -8377,7 +8377,7 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct sk_msg_md, remote_ip4):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_daddr) != 4);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_daddr) != 4);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                                struct sk_msg, sk),
@@ -8388,7 +8388,7 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct sk_msg_md, local_ip4):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_rcv_saddr) != 4);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
@@ -8403,7 +8403,7 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
        case offsetof(struct sk_msg_md, remote_ip6[0]) ...
             offsetof(struct sk_msg_md, remote_ip6[3]):
 #if IS_ENABLED(CONFIG_IPV6)
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_v6_daddr.s6_addr32[0]) != 4);
 
                off = si->off;
@@ -8424,7 +8424,7 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
        case offsetof(struct sk_msg_md, local_ip6[0]) ...
             offsetof(struct sk_msg_md, local_ip6[3]):
 #if IS_ENABLED(CONFIG_IPV6)
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common,
+               BUILD_BUG_ON(sizeof_field(struct sock_common,
                                          skc_v6_rcv_saddr.s6_addr32[0]) != 4);
 
                off = si->off;
@@ -8443,7 +8443,7 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct sk_msg_md, remote_port):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_dport) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_dport) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                                struct sk_msg, sk),
@@ -8457,7 +8457,7 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct sk_msg_md, local_port):
-               BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_num) != 2);
+               BUILD_BUG_ON(sizeof_field(struct sock_common, skc_num) != 2);
 
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
                                                struct sk_msg, sk),
@@ -8847,7 +8847,7 @@ sk_reuseport_is_valid_access(int off, int size,
 
        /* Fields that allow narrowing */
        case bpf_ctx_range(struct sk_reuseport_md, eth_protocol):
-               if (size < FIELD_SIZEOF(struct sk_buff, protocol))
+               if (size < sizeof_field(struct sk_buff, protocol))
                        return false;
                /* fall through */
        case bpf_ctx_range(struct sk_reuseport_md, ip_protocol):
@@ -8865,7 +8865,7 @@ sk_reuseport_is_valid_access(int off, int size,
        *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_reuseport_kern, F), \
                              si->dst_reg, si->src_reg,                 \
                              bpf_target_off(struct sk_reuseport_kern, F, \
-                                            FIELD_SIZEOF(struct sk_reuseport_kern, F), \
+                                            sizeof_field(struct sk_reuseport_kern, F), \
                                             target_size));             \
        })
 
index ca87165..2dbbb03 100644 (file)
@@ -599,8 +599,8 @@ __skb_flow_dissect_gre(const struct sk_buff *skb,
        offset += sizeof(struct gre_base_hdr);
 
        if (hdr->flags & GRE_CSUM)
-               offset += FIELD_SIZEOF(struct gre_full_hdr, csum) +
-                         FIELD_SIZEOF(struct gre_full_hdr, reserved1);
+               offset += sizeof_field(struct gre_full_hdr, csum) +
+                         sizeof_field(struct gre_full_hdr, reserved1);
 
        if (hdr->flags & GRE_KEY) {
                const __be32 *keyid;
@@ -622,11 +622,11 @@ __skb_flow_dissect_gre(const struct sk_buff *skb,
                        else
                                key_keyid->keyid = *keyid & GRE_PPTP_KEY_MASK;
                }
-               offset += FIELD_SIZEOF(struct gre_full_hdr, key);
+               offset += sizeof_field(struct gre_full_hdr, key);
        }
 
        if (hdr->flags & GRE_SEQ)
-               offset += FIELD_SIZEOF(struct pptp_gre_header, seq);
+               offset += sizeof_field(struct pptp_gre_header, seq);
 
        if (gre_ver == 0) {
                if (*p_proto == htons(ETH_P_TEB)) {
@@ -653,7 +653,7 @@ __skb_flow_dissect_gre(const struct sk_buff *skb,
                u8 *ppp_hdr;
 
                if (hdr->flags & GRE_ACK)
-                       offset += FIELD_SIZEOF(struct pptp_gre_header, ack);
+                       offset += sizeof_field(struct pptp_gre_header, ack);
 
                ppp_hdr = __skb_header_pointer(skb, *p_nhoff + offset,
                                               sizeof(_ppp_hdr),
@@ -760,6 +760,31 @@ __skb_flow_dissect_tcp(const struct sk_buff *skb,
 }
 
 static void
+__skb_flow_dissect_ports(const struct sk_buff *skb,
+                        struct flow_dissector *flow_dissector,
+                        void *target_container, void *data, int nhoff,
+                        u8 ip_proto, int hlen)
+{
+       enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX;
+       struct flow_dissector_key_ports *key_ports;
+
+       if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
+               dissector_ports = FLOW_DISSECTOR_KEY_PORTS;
+       else if (dissector_uses_key(flow_dissector,
+                                   FLOW_DISSECTOR_KEY_PORTS_RANGE))
+               dissector_ports = FLOW_DISSECTOR_KEY_PORTS_RANGE;
+
+       if (dissector_ports == FLOW_DISSECTOR_KEY_MAX)
+               return;
+
+       key_ports = skb_flow_dissector_target(flow_dissector,
+                                             dissector_ports,
+                                             target_container);
+       key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
+                                               data, hlen);
+}
+
+static void
 __skb_flow_dissect_ipv4(const struct sk_buff *skb,
                        struct flow_dissector *flow_dissector,
                        void *target_container, void *data, const struct iphdr *iph)
@@ -928,7 +953,6 @@ bool __skb_flow_dissect(const struct net *net,
        struct flow_dissector_key_control *key_control;
        struct flow_dissector_key_basic *key_basic;
        struct flow_dissector_key_addrs *key_addrs;
-       struct flow_dissector_key_ports *key_ports;
        struct flow_dissector_key_tags *key_tags;
        struct flow_dissector_key_vlan *key_vlan;
        struct bpf_prog *attached = NULL;
@@ -945,9 +969,10 @@ bool __skb_flow_dissect(const struct net *net,
                nhoff = skb_network_offset(skb);
                hlen = skb_headlen(skb);
 #if IS_ENABLED(CONFIG_NET_DSA)
-               if (unlikely(skb->dev && netdev_uses_dsa(skb->dev))) {
+               if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
+                            proto == htons(ETH_P_XDSA))) {
                        const struct dsa_device_ops *ops;
-                       int offset;
+                       int offset = 0;
 
                        ops = skb->dev->dsa_ptr->tag_ops;
                        if (ops->flow_dissect &&
@@ -1383,14 +1408,9 @@ ip_proto_again:
                break;
        }
 
-       if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS) &&
-           !(key_control->flags & FLOW_DIS_IS_FRAGMENT)) {
-               key_ports = skb_flow_dissector_target(flow_dissector,
-                                                     FLOW_DISSECTOR_KEY_PORTS,
-                                                     target_container);
-               key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
-                                                       data, hlen);
-       }
+       if (!(key_control->flags & FLOW_DIS_IS_FRAGMENT))
+               __skb_flow_dissect_ports(skb, flow_dissector, target_container,
+                                        data, nhoff, ip_proto, hlen);
 
        /* Process result of IP proto processing */
        switch (fdret) {
index cf52d9c..45b6a59 100644 (file)
@@ -283,7 +283,7 @@ int flow_block_cb_setup_simple(struct flow_block_offload *f,
 }
 EXPORT_SYMBOL(flow_block_cb_setup_simple);
 
-static LIST_HEAD(block_ing_cb_list);
+static LIST_HEAD(block_cb_list);
 
 static struct rhashtable indr_setup_block_ht;
 
@@ -391,20 +391,19 @@ static void flow_indr_block_cb_del(struct flow_indr_block_cb *indr_block_cb)
        kfree(indr_block_cb);
 }
 
-static DEFINE_MUTEX(flow_indr_block_ing_cb_lock);
+static DEFINE_MUTEX(flow_indr_block_cb_lock);
 
-static void flow_block_ing_cmd(struct net_device *dev,
-                              flow_indr_block_bind_cb_t *cb,
-                              void *cb_priv,
-                              enum flow_block_command command)
+static void flow_block_cmd(struct net_device *dev,
+                          flow_indr_block_bind_cb_t *cb, void *cb_priv,
+                          enum flow_block_command command)
 {
-       struct flow_indr_block_ing_entry *entry;
+       struct flow_indr_block_entry *entry;
 
-       mutex_lock(&flow_indr_block_ing_cb_lock);
-       list_for_each_entry(entry, &block_ing_cb_list, list) {
+       mutex_lock(&flow_indr_block_cb_lock);
+       list_for_each_entry(entry, &block_cb_list, list) {
                entry->cb(dev, cb, cb_priv, command);
        }
-       mutex_unlock(&flow_indr_block_ing_cb_lock);
+       mutex_unlock(&flow_indr_block_cb_lock);
 }
 
 int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv,
@@ -424,8 +423,8 @@ int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv,
        if (err)
                goto err_dev_put;
 
-       flow_block_ing_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
-                          FLOW_BLOCK_BIND);
+       flow_block_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
+                      FLOW_BLOCK_BIND);
 
        return 0;
 
@@ -464,8 +463,8 @@ void __flow_indr_block_cb_unregister(struct net_device *dev,
        if (!indr_block_cb)
                return;
 
-       flow_block_ing_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
-                          FLOW_BLOCK_UNBIND);
+       flow_block_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
+                      FLOW_BLOCK_UNBIND);
 
        flow_indr_block_cb_del(indr_block_cb);
        flow_indr_block_dev_put(indr_dev);
@@ -499,21 +498,21 @@ void flow_indr_block_call(struct net_device *dev,
 }
 EXPORT_SYMBOL_GPL(flow_indr_block_call);
 
-void flow_indr_add_block_ing_cb(struct flow_indr_block_ing_entry *entry)
+void flow_indr_add_block_cb(struct flow_indr_block_entry *entry)
 {
-       mutex_lock(&flow_indr_block_ing_cb_lock);
-       list_add_tail(&entry->list, &block_ing_cb_list);
-       mutex_unlock(&flow_indr_block_ing_cb_lock);
+       mutex_lock(&flow_indr_block_cb_lock);
+       list_add_tail(&entry->list, &block_cb_list);
+       mutex_unlock(&flow_indr_block_cb_lock);
 }
-EXPORT_SYMBOL_GPL(flow_indr_add_block_ing_cb);
+EXPORT_SYMBOL_GPL(flow_indr_add_block_cb);
 
-void flow_indr_del_block_ing_cb(struct flow_indr_block_ing_entry *entry)
+void flow_indr_del_block_cb(struct flow_indr_block_entry *entry)
 {
-       mutex_lock(&flow_indr_block_ing_cb_lock);
+       mutex_lock(&flow_indr_block_cb_lock);
        list_del(&entry->list);
-       mutex_unlock(&flow_indr_block_ing_cb_lock);
+       mutex_unlock(&flow_indr_block_cb_lock);
 }
-EXPORT_SYMBOL_GPL(flow_indr_del_block_ing_cb);
+EXPORT_SYMBOL_GPL(flow_indr_del_block_cb);
 
 static int __init init_flow_indr_rhashtable(void)
 {
index 74cfb8b..99a6de5 100644 (file)
@@ -230,9 +230,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)
                fl6.daddr = iph6->daddr;
                fl6.saddr = iph6->saddr;
 
-               err = ipv6_stub->ipv6_dst_lookup(net, skb->sk, &dst, &fl6);
-               if (unlikely(err))
-                       goto err;
+               dst = ipv6_stub->ipv6_dst_lookup_flow(net, skb->sk, &fl6, NULL);
                if (IS_ERR(dst)) {
                        err = PTR_ERR(dst);
                        goto err;
index ae3bcb1..5c46242 100644 (file)
@@ -1459,14 +1459,17 @@ static int netdev_queue_add_kobject(struct net_device *dev, int index)
        struct kobject *kobj = &queue->kobj;
        int error = 0;
 
+       /* Kobject_put later will trigger netdev_queue_release call
+        * which decreases dev refcount: Take that reference here
+        */
+       dev_hold(queue->dev);
+
        kobj->kset = dev->queues_kset;
        error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL,
                                     "tx-%u", index);
        if (error)
                goto err;
 
-       dev_hold(queue->dev);
-
 #ifdef CONFIG_BQL
        error = sysfs_create_group(kobj, &dql_group);
        if (error)
index 0b5ccb7..02916f4 100644 (file)
@@ -1250,7 +1250,9 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
                vf_spoofchk.vf =
                vf_linkstate.vf =
                vf_rss_query_en.vf =
-               vf_trust.vf = ivi.vf;
+               vf_trust.vf =
+               node_guid.vf =
+               port_guid.vf = ivi.vf;
 
        memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
        memcpy(vf_broadcast.broadcast, dev->broadcast, dev->addr_len);
index 867e61d..973a71f 100644 (file)
@@ -5484,7 +5484,7 @@ static void skb_mod_eth_type(struct sk_buff *skb, struct ethhdr *hdr,
  * Returns 0 on success, -errno otherwise.
  */
 int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto,
-                 int mac_len)
+                 int mac_len, bool ethernet)
 {
        struct mpls_shim_hdr *lse;
        int err;
@@ -5515,7 +5515,7 @@ int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto,
        lse->label_stack_entry = mpls_lse;
        skb_postpush_rcsum(skb, lse, MPLS_HLEN);
 
-       if (skb->dev && skb->dev->type == ARPHRD_ETHER)
+       if (ethernet)
                skb_mod_eth_type(skb, eth_hdr(skb), mpls_proto);
        skb->protocol = mpls_proto;
 
@@ -5529,12 +5529,14 @@ EXPORT_SYMBOL_GPL(skb_mpls_push);
  * @skb: buffer
  * @next_proto: ethertype of header after popped MPLS header
  * @mac_len: length of the MAC header
+ * @ethernet: flag to indicate if ethernet header is present in packet
  *
  * Expects skb->data at mac header.
  *
  * Returns 0 on success, -errno otherwise.
  */
-int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len)
+int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len,
+                bool ethernet)
 {
        int err;
 
@@ -5553,7 +5555,7 @@ int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len)
        skb_reset_mac_header(skb);
        skb_set_network_header(skb, mac_len);
 
-       if (skb->dev && skb->dev->type == ARPHRD_ETHER) {
+       if (ethernet) {
                struct ethhdr *hdr;
 
                /* use mpls_hdr() to get ethertype to account for VLANs. */
index e334fad..8310714 100644 (file)
@@ -36,7 +36,7 @@ static u32 xdp_mem_id_hashfn(const void *data, u32 len, u32 seed)
        const u32 *k = data;
        const u32 key = *k;
 
-       BUILD_BUG_ON(FIELD_SIZEOF(struct xdp_mem_allocator, mem.id)
+       BUILD_BUG_ON(sizeof_field(struct xdp_mem_allocator, mem.id)
                     != sizeof(u32));
 
        /* Use cyclic increasing ID as direct hash key */
@@ -56,7 +56,7 @@ static const struct rhashtable_params mem_id_rht_params = {
        .nelem_hint = 64,
        .head_offset = offsetof(struct xdp_mem_allocator, node),
        .key_offset  = offsetof(struct xdp_mem_allocator, mem.id),
-       .key_len = FIELD_SIZEOF(struct xdp_mem_allocator, mem.id),
+       .key_len = sizeof_field(struct xdp_mem_allocator, mem.id),
        .max_size = MEM_ID_MAX,
        .min_size = 8,
        .automatic_shrinking = true,
@@ -80,12 +80,8 @@ static void mem_xa_remove(struct xdp_mem_allocator *xa)
 {
        trace_mem_disconnect(xa);
 
-       mutex_lock(&mem_id_lock);
-
        if (!rhashtable_remove_fast(mem_id_ht, &xa->node, mem_id_rht_params))
                call_rcu(&xa->rcu, __xdp_mem_allocator_rcu_free);
-
-       mutex_unlock(&mem_id_lock);
 }
 
 static void mem_allocator_disconnect(void *allocator)
@@ -93,6 +89,8 @@ static void mem_allocator_disconnect(void *allocator)
        struct xdp_mem_allocator *xa;
        struct rhashtable_iter iter;
 
+       mutex_lock(&mem_id_lock);
+
        rhashtable_walk_enter(mem_id_ht, &iter);
        do {
                rhashtable_walk_start(&iter);
@@ -106,6 +104,8 @@ static void mem_allocator_disconnect(void *allocator)
 
        } while (xa == ERR_PTR(-EAGAIN));
        rhashtable_walk_exit(&iter);
+
+       mutex_unlock(&mem_id_lock);
 }
 
 static void mem_id_disconnect(int id)
index 25aab67..1e5e08c 100644 (file)
@@ -210,7 +210,7 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req
        final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
        rcu_read_unlock();
 
-       dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
        if (IS_ERR(dst)) {
                err = PTR_ERR(dst);
                dst = NULL;
@@ -282,7 +282,7 @@ static void dccp_v6_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
        security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));
 
        /* sk = NULL, but it is safe for now. RST socket required. */
-       dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL);
+       dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL);
        if (!IS_ERR(dst)) {
                skb_dst_set(skb, dst);
                ip6_xmit(ctl_sk, skb, &fl6, 0, NULL, 0, 0);
@@ -912,7 +912,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk));
        final_p = fl6_update_dst(&fl6, opt, &final);
 
-       dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
        if (IS_ERR(dst)) {
                err = PTR_ERR(dst);
                goto failure;
index a52e8ba..4af8a98 100644 (file)
@@ -1132,7 +1132,7 @@ static int __init dccp_init(void)
        int rc;
 
        BUILD_BUG_ON(sizeof(struct dccp_skb_cb) >
-                    FIELD_SIZEOF(struct sk_buff, cb));
+                    sizeof_field(struct sk_buff, cb));
        rc = percpu_counter_init(&dccp_orphan_count, 0, GFP_KERNEL);
        if (rc)
                goto out_fail;
index f509b49..b01e1ba 100644 (file)
@@ -227,8 +227,13 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        struct hsr_port *master;
 
        master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
-       skb->dev = master->dev;
-       hsr_forward_skb(skb, master);
+       if (master) {
+               skb->dev = master->dev;
+               hsr_forward_skb(skb, master);
+       } else {
+               atomic_long_inc(&dev->tx_dropped);
+               dev_kfree_skb_any(skb);
+       }
        return NETDEV_TX_OK;
 }
 
index a4b5bd4..e4632bd 100644 (file)
@@ -1496,11 +1496,6 @@ skip:
        }
 }
 
-static bool inetdev_valid_mtu(unsigned int mtu)
-{
-       return mtu >= IPV4_MIN_MTU;
-}
-
 static void inetdev_send_gratuitous_arp(struct net_device *dev,
                                        struct in_device *in_dev)
 
index 44bfeec..5fd6e8e 100644 (file)
@@ -127,7 +127,7 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
                if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr)))
                        return -EINVAL;
 
-               ershdr = (struct erspan_base_hdr *)options;
+               ershdr = (struct erspan_base_hdr *)(skb->data + nhs + hdr_len);
                tpi->key = cpu_to_be32(get_session_id(ershdr));
        }
 
index 572b630..8274f98 100644 (file)
@@ -1464,8 +1464,8 @@ static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
        [IFLA_GRE_OFLAGS]       = { .type = NLA_U16 },
        [IFLA_GRE_IKEY]         = { .type = NLA_U32 },
        [IFLA_GRE_OKEY]         = { .type = NLA_U32 },
-       [IFLA_GRE_LOCAL]        = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
-       [IFLA_GRE_REMOTE]       = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
+       [IFLA_GRE_LOCAL]        = { .len = sizeof_field(struct iphdr, saddr) },
+       [IFLA_GRE_REMOTE]       = { .len = sizeof_field(struct iphdr, daddr) },
        [IFLA_GRE_TTL]          = { .type = NLA_U8 },
        [IFLA_GRE_TOS]          = { .type = NLA_U8 },
        [IFLA_GRE_PMTUDISC]     = { .type = NLA_U8 },
index 9d83cb3..14db1e0 100644 (file)
@@ -1258,15 +1258,18 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
                cork->addr = ipc->addr;
        }
 
-       /*
-        * We steal reference to this route, caller should not release it
-        */
-       *rtp = NULL;
        cork->fragsize = ip_sk_use_pmtu(sk) ?
-                        dst_mtu(&rt->dst) : rt->dst.dev->mtu;
+                        dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu);
+
+       if (!inetdev_valid_mtu(cork->fragsize))
+               return -ENETUNREACH;
 
        cork->gso_size = ipc->gso_size;
+
        cork->dst = &rt->dst;
+       /* We stole this route, caller should not release it. */
+       *rtp = NULL;
+
        cork->length = 0;
        cork->ttl = ipc->ttl;
        cork->tos = ipc->tos;
index cfb0256..9b153c7 100644 (file)
@@ -580,8 +580,8 @@ static const struct nla_policy vti_policy[IFLA_VTI_MAX + 1] = {
        [IFLA_VTI_LINK]         = { .type = NLA_U32 },
        [IFLA_VTI_IKEY]         = { .type = NLA_U32 },
        [IFLA_VTI_OKEY]         = { .type = NLA_U32 },
-       [IFLA_VTI_LOCAL]        = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
-       [IFLA_VTI_REMOTE]       = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
+       [IFLA_VTI_LOCAL]        = { .len = sizeof_field(struct iphdr, saddr) },
+       [IFLA_VTI_REMOTE]       = { .len = sizeof_field(struct iphdr, daddr) },
        [IFLA_VTI_FWMARK]       = { .type = NLA_U32 },
 };
 
index 8a39ee7..3e50ac2 100644 (file)
@@ -3949,7 +3949,7 @@ void __init tcp_init(void)
 
        BUILD_BUG_ON(TCP_MIN_SND_MSS <= MAX_TCP_OPTION_SPACE);
        BUILD_BUG_ON(sizeof(struct tcp_skb_cb) >
-                    FIELD_SIZEOF(struct sk_buff, cb));
+                    sizeof_field(struct sk_buff, cb));
 
        percpu_counter_init(&tcp_sockets_allocated, 0, GFP_KERNEL);
        percpu_counter_init(&tcp_orphan_count, 0, GFP_KERNEL);
index be6d22b..b184f03 100644 (file)
@@ -755,8 +755,9 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb
                        min_t(unsigned int, eff_sacks,
                              (remaining - TCPOLEN_SACK_BASE_ALIGNED) /
                              TCPOLEN_SACK_PERBLOCK);
-               size += TCPOLEN_SACK_BASE_ALIGNED +
-                       opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK;
+               if (likely(opts->num_sack_blocks))
+                       size += TCPOLEN_SACK_BASE_ALIGNED +
+                               opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK;
        }
 
        return size;
index dd5a631..1097b43 100644 (file)
@@ -434,6 +434,7 @@ void tcp_retransmit_timer(struct sock *sk)
        struct net *net = sock_net(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct request_sock *req;
+       struct sk_buff *skb;
 
        req = rcu_dereference_protected(tp->fastopen_rsk,
                                        lockdep_sock_is_held(sk));
@@ -446,7 +447,12 @@ void tcp_retransmit_timer(struct sock *sk)
                 */
                return;
        }
-       if (!tp->packets_out || WARN_ON_ONCE(tcp_rtx_queue_empty(sk)))
+
+       if (!tp->packets_out)
+               return;
+
+       skb = tcp_rtx_queue_head(sk);
+       if (WARN_ON_ONCE(!skb))
                return;
 
        tp->tlp_high_seq = 0;
@@ -480,7 +486,7 @@ void tcp_retransmit_timer(struct sock *sk)
                        goto out;
                }
                tcp_enter_loss(sk);
-               tcp_retransmit_skb(sk, tcp_rtx_queue_head(sk), 1);
+               tcp_retransmit_skb(sk, skb, 1);
                __sk_dst_reset(sk);
                goto out_reset_timer;
        }
index 2fc0792..ea00ce3 100644 (file)
@@ -129,11 +129,12 @@ int inet6addr_validator_notifier_call_chain(unsigned long val, void *v)
 }
 EXPORT_SYMBOL(inet6addr_validator_notifier_call_chain);
 
-static int eafnosupport_ipv6_dst_lookup(struct net *net, struct sock *u1,
-                                       struct dst_entry **u2,
-                                       struct flowi6 *u3)
+static struct dst_entry *eafnosupport_ipv6_dst_lookup_flow(struct net *net,
+                                                          const struct sock *sk,
+                                                          struct flowi6 *fl6,
+                                                          const struct in6_addr *final_dst)
 {
-       return -EAFNOSUPPORT;
+       return ERR_PTR(-EAFNOSUPPORT);
 }
 
 static int eafnosupport_ipv6_route_input(struct sk_buff *skb)
@@ -190,7 +191,7 @@ static int eafnosupport_ip6_del_rt(struct net *net, struct fib6_info *rt)
 }
 
 const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) {
-       .ipv6_dst_lookup   = eafnosupport_ipv6_dst_lookup,
+       .ipv6_dst_lookup_flow = eafnosupport_ipv6_dst_lookup_flow,
        .ipv6_route_input  = eafnosupport_ipv6_route_input,
        .fib6_get_table    = eafnosupport_fib6_get_table,
        .fib6_table_lookup = eafnosupport_fib6_table_lookup,
index 60e2ff9..d727c3b 100644 (file)
@@ -765,7 +765,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
                                         &final);
                rcu_read_unlock();
 
-               dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+               dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
                if (IS_ERR(dst)) {
                        sk->sk_route_caps = 0;
                        sk->sk_err_soft = -PTR_ERR(dst);
@@ -946,7 +946,7 @@ static int ipv6_route_input(struct sk_buff *skb)
 static const struct ipv6_stub ipv6_stub_impl = {
        .ipv6_sock_mc_join = ipv6_sock_mc_join,
        .ipv6_sock_mc_drop = ipv6_sock_mc_drop,
-       .ipv6_dst_lookup   = ip6_dst_lookup,
+       .ipv6_dst_lookup_flow = ip6_dst_lookup_flow,
        .ipv6_route_input  = ipv6_route_input,
        .fib6_get_table    = fib6_get_table,
        .fib6_table_lookup = fib6_table_lookup,
index 96f9392..390bedd 100644 (file)
@@ -85,7 +85,7 @@ int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr)
        final_p = fl6_update_dst(&fl6, opt, &final);
        rcu_read_unlock();
 
-       dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
        if (IS_ERR(dst)) {
                err = PTR_ERR(dst);
                goto out;
index 0a0945a..fe9cb8d 100644 (file)
@@ -48,7 +48,7 @@ struct dst_entry *inet6_csk_route_req(const struct sock *sk,
        fl6->flowi6_uid = sk->sk_uid;
        security_req_classify_flow(req, flowi6_to_flowi(fl6));
 
-       dst = ip6_dst_lookup_flow(sk, fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
        if (IS_ERR(dst))
                return NULL;
 
@@ -103,7 +103,7 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
 
        dst = __inet6_csk_dst_check(sk, np->dst_cookie);
        if (!dst) {
-               dst = ip6_dst_lookup_flow(sk, fl6, final_p);
+               dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
 
                if (!IS_ERR(dst))
                        ip6_dst_store(sk, dst, NULL, NULL);
index 923034c..9d09652 100644 (file)
@@ -2170,8 +2170,8 @@ static const struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = {
        [IFLA_GRE_OFLAGS]      = { .type = NLA_U16 },
        [IFLA_GRE_IKEY]        = { .type = NLA_U32 },
        [IFLA_GRE_OKEY]        = { .type = NLA_U32 },
-       [IFLA_GRE_LOCAL]       = { .len = FIELD_SIZEOF(struct ipv6hdr, saddr) },
-       [IFLA_GRE_REMOTE]      = { .len = FIELD_SIZEOF(struct ipv6hdr, daddr) },
+       [IFLA_GRE_LOCAL]       = { .len = sizeof_field(struct ipv6hdr, saddr) },
+       [IFLA_GRE_REMOTE]      = { .len = sizeof_field(struct ipv6hdr, daddr) },
        [IFLA_GRE_TTL]         = { .type = NLA_U8 },
        [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 },
        [IFLA_GRE_FLOWINFO]    = { .type = NLA_U32 },
index 945508a..0873044 100644 (file)
@@ -1144,19 +1144,19 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup);
  *     It returns a valid dst pointer on success, or a pointer encoded
  *     error code.
  */
-struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
+struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6,
                                      const struct in6_addr *final_dst)
 {
        struct dst_entry *dst = NULL;
        int err;
 
-       err = ip6_dst_lookup_tail(sock_net(sk), sk, &dst, fl6);
+       err = ip6_dst_lookup_tail(net, sk, &dst, fl6);
        if (err)
                return ERR_PTR(err);
        if (final_dst)
                fl6->daddr = *final_dst;
 
-       return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
+       return xfrm_lookup_route(net, dst, flowi6_to_flowi(fl6), sk, 0);
 }
 EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
 
@@ -1188,7 +1188,7 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
        if (dst)
                return dst;
 
-       dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_dst);
        if (connected && !IS_ERR(dst))
                ip6_sk_dst_store_flow(sk, dst_clone(dst), fl6);
 
index a77f6b7..dfe5e60 100644 (file)
@@ -925,7 +925,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
        fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
 
-       dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
        if (IS_ERR(dst)) {
                err = PTR_ERR(dst);
                goto out;
index 16632e0..30915f6 100644 (file)
@@ -235,7 +235,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
                fl6.flowi6_uid = sk->sk_uid;
                security_req_classify_flow(req, flowi6_to_flowi(&fl6));
 
-               dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+               dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
                if (IS_ERR(dst))
                        goto out_free;
        }
index 81f5133..df5fd91 100644 (file)
@@ -275,7 +275,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 
        security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-       dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
        if (IS_ERR(dst)) {
                err = PTR_ERR(dst);
                goto failure;
@@ -906,7 +906,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
         * Underlying function will use this to retrieve the network
         * namespace
         */
-       dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL);
+       dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL);
        if (!IS_ERR(dst)) {
                skb_dst_set(buff, dst);
                ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass,
index ebb62a4..c4bdcbc 100644 (file)
@@ -50,7 +50,7 @@ static struct iucv_interface *pr_iucv;
 static const u8 iprm_shutdown[8] =
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
 
-#define TRGCLS_SIZE    FIELD_SIZEOF(struct iucv_message, class)
+#define TRGCLS_SIZE    sizeof_field(struct iucv_message, class)
 
 #define __iucv_sock_wait(sk, condition, timeo, ret)                    \
 do {                                                                   \
index 802f19a..d148766 100644 (file)
@@ -615,7 +615,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
        fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
 
-       dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
        if (IS_ERR(dst)) {
                err = PTR_ERR(dst);
                goto out;
index c312741..4701edf 100644 (file)
@@ -617,16 +617,15 @@ static struct net_device *inet6_fib_lookup_dev(struct net *net,
        struct net_device *dev;
        struct dst_entry *dst;
        struct flowi6 fl6;
-       int err;
 
        if (!ipv6_stub)
                return ERR_PTR(-EAFNOSUPPORT);
 
        memset(&fl6, 0, sizeof(fl6));
        memcpy(&fl6.daddr, addr, sizeof(struct in6_addr));
-       err = ipv6_stub->ipv6_dst_lookup(net, NULL, &dst, &fl6);
-       if (err)
-               return ERR_PTR(err);
+       dst = ipv6_stub->ipv6_dst_lookup_flow(net, NULL, &fl6, NULL);
+       if (IS_ERR(dst))
+               return ERR_CAST(dst);
 
        dev = dst->dev;
        dev_hold(dev);
index 062b73a..c26a566 100644 (file)
@@ -7595,7 +7595,7 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len)
                return -EINVAL;
        if (len == 0)
                return -EINVAL;
-       if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
+       if (reg * NFT_REG32_SIZE + len > sizeof_field(struct nft_regs, data))
                return -ERANGE;
 
        return 0;
@@ -7643,7 +7643,7 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
                if (len == 0)
                        return -EINVAL;
                if (reg * NFT_REG32_SIZE + len >
-                   FIELD_SIZEOF(struct nft_regs, data))
+                   sizeof_field(struct nft_regs, data))
                        return -ERANGE;
 
                if (data != NULL && type != NFT_DATA_VALUE)
index 68f17a6..431f3b8 100644 (file)
@@ -588,7 +588,7 @@ static int nft_offload_netdev_event(struct notifier_block *this,
        return NOTIFY_DONE;
 }
 
-static struct flow_indr_block_ing_entry block_ing_entry = {
+static struct flow_indr_block_entry block_ing_entry = {
        .cb     = nft_indr_block_cb,
        .list   = LIST_HEAD_INIT(block_ing_entry.list),
 };
@@ -605,13 +605,13 @@ int nft_offload_init(void)
        if (err < 0)
                return err;
 
-       flow_indr_add_block_ing_cb(&block_ing_entry);
+       flow_indr_add_block_cb(&block_ing_entry);
 
        return 0;
 }
 
 void nft_offload_exit(void)
 {
-       flow_indr_del_block_ing_cb(&block_ing_entry);
+       flow_indr_del_block_cb(&block_ing_entry);
        unregister_netdevice_notifier(&nft_offload_netdev_notifier);
 }
index 7525063..de3a959 100644 (file)
@@ -236,7 +236,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
        nla_strlcpy(helper->name,
                    tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN);
        size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
-       if (size > FIELD_SIZEOF(struct nf_conn_help, data)) {
+       if (size > sizeof_field(struct nf_conn_help, data)) {
                ret = -ENOMEM;
                goto err2;
        }
index 46ca8bc..faea72c 100644 (file)
@@ -440,12 +440,12 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
 
                switch (ctx->family) {
                case NFPROTO_IPV4:
-                       len = FIELD_SIZEOF(struct nf_conntrack_tuple,
+                       len = sizeof_field(struct nf_conntrack_tuple,
                                           src.u3.ip);
                        break;
                case NFPROTO_IPV6:
                case NFPROTO_INET:
-                       len = FIELD_SIZEOF(struct nf_conntrack_tuple,
+                       len = sizeof_field(struct nf_conntrack_tuple,
                                           src.u3.ip6);
                        break;
                default:
@@ -457,20 +457,20 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
                if (tb[NFTA_CT_DIRECTION] == NULL)
                        return -EINVAL;
 
-               len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip);
+               len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip);
                break;
        case NFT_CT_SRC_IP6:
        case NFT_CT_DST_IP6:
                if (tb[NFTA_CT_DIRECTION] == NULL)
                        return -EINVAL;
 
-               len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip6);
+               len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip6);
                break;
        case NFT_CT_PROTO_SRC:
        case NFT_CT_PROTO_DST:
                if (tb[NFTA_CT_DIRECTION] == NULL)
                        return -EINVAL;
-               len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
+               len = sizeof_field(struct nf_conntrack_tuple, src.u.all);
                break;
        case NFT_CT_BYTES:
        case NFT_CT_PKTS:
@@ -551,7 +551,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
        case NFT_CT_MARK:
                if (tb[NFTA_CT_DIRECTION])
                        return -EINVAL;
-               len = FIELD_SIZEOF(struct nf_conn, mark);
+               len = sizeof_field(struct nf_conn, mark);
                break;
 #endif
 #ifdef CONFIG_NF_CONNTRACK_LABELS
index 39dc94f..bc9fd98 100644 (file)
@@ -43,7 +43,7 @@ static int nft_masq_init(const struct nft_ctx *ctx,
                         const struct nft_expr *expr,
                         const struct nlattr * const tb[])
 {
-       u32 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
+       u32 plen = sizeof_field(struct nf_nat_range, min_addr.all);
        struct nft_masq *priv = nft_expr_priv(expr);
        int err;
 
index c3c93e9..8b44a4d 100644 (file)
@@ -141,10 +141,10 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 
        switch (family) {
        case NFPROTO_IPV4:
-               alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip);
+               alen = sizeof_field(struct nf_nat_range, min_addr.ip);
                break;
        case NFPROTO_IPV6:
-               alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip6);
+               alen = sizeof_field(struct nf_nat_range, min_addr.ip6);
                break;
        default:
                return -EAFNOSUPPORT;
@@ -171,7 +171,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
                }
        }
 
-       plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
+       plen = sizeof_field(struct nf_nat_range, min_addr.all);
        if (tb[NFTA_NAT_REG_PROTO_MIN]) {
                priv->sreg_proto_min =
                        nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]);
index 43eeb1f..5b77917 100644 (file)
@@ -48,7 +48,7 @@ static int nft_redir_init(const struct nft_ctx *ctx,
        unsigned int plen;
        int err;
 
-       plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
+       plen = sizeof_field(struct nf_nat_range, min_addr.all);
        if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
                priv->sreg_proto_min =
                        nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]);
index f92a82c..4c33dfc 100644 (file)
@@ -218,14 +218,14 @@ static int nft_tproxy_init(const struct nft_ctx *ctx,
 
        switch (priv->family) {
        case NFPROTO_IPV4:
-               alen = FIELD_SIZEOF(union nf_inet_addr, in);
+               alen = sizeof_field(union nf_inet_addr, in);
                err = nf_defrag_ipv4_enable(ctx->net);
                if (err)
                        return err;
                break;
 #if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
        case NFPROTO_IPV6:
-               alen = FIELD_SIZEOF(union nf_inet_addr, in6);
+               alen = sizeof_field(union nf_inet_addr, in6);
                err = nf_defrag_ipv6_enable(ctx->net);
                if (err)
                        return err;
index 2236455..37253d3 100644 (file)
@@ -30,7 +30,7 @@ static unsigned int jhash_rnd __read_mostly;
 
 static unsigned int xt_rateest_hash(const char *name)
 {
-       return jhash(name, FIELD_SIZEOF(struct xt_rateest, name), jhash_rnd) &
+       return jhash(name, sizeof_field(struct xt_rateest, name), jhash_rnd) &
               (RATEEST_HSIZE - 1);
 }
 
index 90b2ab9..4e31721 100644 (file)
@@ -2755,7 +2755,7 @@ static int __init netlink_proto_init(void)
        if (err != 0)
                goto out;
 
-       BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
+       BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > sizeof_field(struct sk_buff, cb));
 
        nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
        if (!nl_table)
index 9dd8a10..7d8e10e 100644 (file)
@@ -44,7 +44,8 @@ static int __nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb,
                t.len = 0;
        }
        t.cs_change = cs_change;
-       t.delay_usecs = nspi->xfer_udelay;
+       t.delay.value = nspi->xfer_udelay;
+       t.delay.unit = SPI_DELAY_UNIT_USECS;
        t.speed_hz = nspi->xfer_speed_hz;
 
        spi_message_init(&m);
@@ -216,7 +217,8 @@ static struct sk_buff *__nci_spi_read(struct nci_spi *nspi)
        rx.rx_buf = skb_put(skb, rx_len);
        rx.len = rx_len;
        rx.cs_change = 0;
-       rx.delay_usecs = nspi->xfer_udelay;
+       rx.delay.value = nspi->xfer_udelay;
+       rx.delay.unit = SPI_DELAY_UNIT_USECS;
        rx.speed_hz = nspi->xfer_speed_hz;
        spi_message_add_tail(&rx, &m);
 
index 12936c1..4c83954 100644 (file)
@@ -166,7 +166,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
        int err;
 
        err = skb_mpls_push(skb, mpls->mpls_lse, mpls->mpls_ethertype,
-                           skb->mac_len);
+                           skb->mac_len,
+                           ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET);
        if (err)
                return err;
 
@@ -179,7 +180,8 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
 {
        int err;
 
-       err = skb_mpls_pop(skb, ethertype, skb->mac_len);
+       err = skb_mpls_pop(skb, ethertype, skb->mac_len,
+                          ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET);
        if (err)
                return err;
 
index df9c80b..e726159 100644 (file)
@@ -903,6 +903,17 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
        }
        err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype);
 
+       if (err == NF_ACCEPT &&
+           ct->status & IPS_SRC_NAT && ct->status & IPS_DST_NAT) {
+               if (maniptype == NF_NAT_MANIP_SRC)
+                       maniptype = NF_NAT_MANIP_DST;
+               else
+                       maniptype = NF_NAT_MANIP_SRC;
+
+               err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range,
+                                        maniptype);
+       }
+
        /* Mark NAT done if successful and update the flow key. */
        if (err == NF_ACCEPT)
                ovs_nat_update_key(key, skb, maniptype);
index 1047e80..e3a37d2 100644 (file)
@@ -2497,7 +2497,7 @@ static int __init dp_init(void)
 {
        int err;
 
-       BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb));
+       BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > sizeof_field(struct sk_buff, cb));
 
        pr_info("Open vSwitch switching datapath\n");
 
index fd8ed76..758a8c7 100644 (file)
@@ -37,7 +37,7 @@ enum sw_flow_mac_proto {
  * matching for small options.
  */
 #define TUN_METADATA_OFFSET(opt_len) \
-       (FIELD_SIZEOF(struct sw_flow_key, tun_opts) - opt_len)
+       (sizeof_field(struct sw_flow_key, tun_opts) - opt_len)
 #define TUN_METADATA_OPTS(flow_key, opt_len) \
        ((void *)((flow_key)->tun_opts + TUN_METADATA_OFFSET(opt_len)))
 
@@ -52,7 +52,7 @@ struct vlan_head {
 
 #define OVS_SW_FLOW_KEY_METADATA_SIZE                  \
        (offsetof(struct sw_flow_key, recirc_id) +      \
-       FIELD_SIZEOF(struct sw_flow_key, recirc_id))
+       sizeof_field(struct sw_flow_key, recirc_id))
 
 struct ovs_key_nsh {
        struct ovs_nsh_key_base base;
index d72ddb6..9d3c4d2 100644 (file)
@@ -972,7 +972,7 @@ static int __init af_rxrpc_init(void)
        int ret = -1;
        unsigned int tmp;
 
-       BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > FIELD_SIZEOF(struct sk_buff, cb));
+       BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > sizeof_field(struct sk_buff, cb));
 
        get_random_bytes(&tmp, sizeof(tmp));
        tmp &= 0x3fffffff;
index ae0de37..f685c0d 100644 (file)
@@ -312,7 +312,7 @@ static void tcf_ct_act_set_labels(struct nf_conn *ct,
                                  u32 *labels_m)
 {
 #if IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS)
-       size_t labels_sz = FIELD_SIZEOF(struct tcf_ct_params, labels);
+       size_t labels_sz = sizeof_field(struct tcf_ct_params, labels);
 
        if (!memchr_inv(labels_m, 0, labels_sz))
                return;
@@ -329,6 +329,7 @@ static int tcf_ct_act_nat(struct sk_buff *skb,
                          bool commit)
 {
 #if IS_ENABLED(CONFIG_NF_NAT)
+       int err;
        enum nf_nat_manip_type maniptype;
 
        if (!(ct_action & TCA_CT_ACT_NAT))
@@ -359,7 +360,17 @@ static int tcf_ct_act_nat(struct sk_buff *skb,
                return NF_ACCEPT;
        }
 
-       return ct_nat_execute(skb, ct, ctinfo, range, maniptype);
+       err = ct_nat_execute(skb, ct, ctinfo, range, maniptype);
+       if (err == NF_ACCEPT &&
+           ct->status & IPS_SRC_NAT && ct->status & IPS_DST_NAT) {
+               if (maniptype == NF_NAT_MANIP_SRC)
+                       maniptype = NF_NAT_MANIP_DST;
+               else
+                       maniptype = NF_NAT_MANIP_SRC;
+
+               err = ct_nat_execute(skb, ct, ctinfo, range, maniptype);
+       }
+       return err;
 #else
        return NF_ACCEPT;
 #endif
@@ -925,7 +936,7 @@ static struct tc_action_ops act_ct_ops = {
 
 static __net_init int ct_init_net(struct net *net)
 {
-       unsigned int n_bits = FIELD_SIZEOF(struct tcf_ct_params, labels) * 8;
+       unsigned int n_bits = sizeof_field(struct tcf_ct_params, labels) * 8;
        struct tc_ct_action_net *tn = net_generic(net, ct_net_id);
 
        if (nf_connlabels_get(net, n_bits - 1)) {
index 325eddc..be3f215 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /* Copyright (C) 2019 Netronome Systems, Inc. */
 
+#include <linux/if_arp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -76,12 +77,14 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a,
 
        switch (p->tcfm_action) {
        case TCA_MPLS_ACT_POP:
-               if (skb_mpls_pop(skb, p->tcfm_proto, mac_len))
+               if (skb_mpls_pop(skb, p->tcfm_proto, mac_len,
+                                skb->dev && skb->dev->type == ARPHRD_ETHER))
                        goto drop;
                break;
        case TCA_MPLS_ACT_PUSH:
                new_lse = tcf_mpls_get_lse(NULL, p, !eth_p_mpls(skb->protocol));
-               if (skb_mpls_push(skb, new_lse, p->tcfm_proto, mac_len))
+               if (skb_mpls_push(skb, new_lse, p->tcfm_proto, mac_len,
+                                 skb->dev && skb->dev->type == ARPHRD_ETHER))
                        goto drop;
                break;
        case TCA_MPLS_ACT_MODIFY:
index 20d60b8..6a0eaca 100644 (file)
@@ -626,15 +626,15 @@ static void tcf_chain_flush(struct tcf_chain *chain, bool rtnl_held)
 static int tcf_block_setup(struct tcf_block *block,
                           struct flow_block_offload *bo);
 
-static void tc_indr_block_ing_cmd(struct net_device *dev,
-                                 struct tcf_block *block,
-                                 flow_indr_block_bind_cb_t *cb,
-                                 void *cb_priv,
-                                 enum flow_block_command command)
+static void tc_indr_block_cmd(struct net_device *dev, struct tcf_block *block,
+                             flow_indr_block_bind_cb_t *cb, void *cb_priv,
+                             enum flow_block_command command, bool ingress)
 {
        struct flow_block_offload bo = {
                .command        = command,
-               .binder_type    = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS,
+               .binder_type    = ingress ?
+                                 FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS :
+                                 FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS,
                .net            = dev_net(dev),
                .block_shared   = tcf_block_non_null_shared(block),
        };
@@ -652,9 +652,10 @@ static void tc_indr_block_ing_cmd(struct net_device *dev,
        up_write(&block->cb_lock);
 }
 
-static struct tcf_block *tc_dev_ingress_block(struct net_device *dev)
+static struct tcf_block *tc_dev_block(struct net_device *dev, bool ingress)
 {
        const struct Qdisc_class_ops *cops;
+       const struct Qdisc_ops *ops;
        struct Qdisc *qdisc;
 
        if (!dev_ingress_queue(dev))
@@ -664,24 +665,37 @@ static struct tcf_block *tc_dev_ingress_block(struct net_device *dev)
        if (!qdisc)
                return NULL;
 
-       cops = qdisc->ops->cl_ops;
+       ops = qdisc->ops;
+       if (!ops)
+               return NULL;
+
+       if (!ingress && !strcmp("ingress", ops->id))
+               return NULL;
+
+       cops = ops->cl_ops;
        if (!cops)
                return NULL;
 
        if (!cops->tcf_block)
                return NULL;
 
-       return cops->tcf_block(qdisc, TC_H_MIN_INGRESS, NULL);
+       return cops->tcf_block(qdisc,
+                              ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS,
+                              NULL);
 }
 
-static void tc_indr_block_get_and_ing_cmd(struct net_device *dev,
-                                         flow_indr_block_bind_cb_t *cb,
-                                         void *cb_priv,
-                                         enum flow_block_command command)
+static void tc_indr_block_get_and_cmd(struct net_device *dev,
+                                     flow_indr_block_bind_cb_t *cb,
+                                     void *cb_priv,
+                                     enum flow_block_command command)
 {
-       struct tcf_block *block = tc_dev_ingress_block(dev);
+       struct tcf_block *block;
+
+       block = tc_dev_block(dev, true);
+       tc_indr_block_cmd(dev, block, cb, cb_priv, command, true);
 
-       tc_indr_block_ing_cmd(dev, block, cb, cb_priv, command);
+       block = tc_dev_block(dev, false);
+       tc_indr_block_cmd(dev, block, cb, cb_priv, command, false);
 }
 
 static void tc_indr_block_call(struct tcf_block *block,
@@ -2721,13 +2735,19 @@ static int tc_chain_tmplt_add(struct tcf_chain *chain, struct net *net,
                              struct netlink_ext_ack *extack)
 {
        const struct tcf_proto_ops *ops;
+       char name[IFNAMSIZ];
        void *tmplt_priv;
 
        /* If kind is not set, user did not specify template. */
        if (!tca[TCA_KIND])
                return 0;
 
-       ops = tcf_proto_lookup_ops(nla_data(tca[TCA_KIND]), true, extack);
+       if (tcf_proto_check_kind(tca[TCA_KIND], name)) {
+               NL_SET_ERR_MSG(extack, "Specified TC chain template name too long");
+               return -EINVAL;
+       }
+
+       ops = tcf_proto_lookup_ops(name, true, extack);
        if (IS_ERR(ops))
                return PTR_ERR(ops);
        if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) {
@@ -3626,9 +3646,9 @@ static struct pernet_operations tcf_net_ops = {
        .size = sizeof(struct tcf_net),
 };
 
-static struct flow_indr_block_ing_entry block_ing_entry = {
-       .cb = tc_indr_block_get_and_ing_cmd,
-       .list = LIST_HEAD_INIT(block_ing_entry.list),
+static struct flow_indr_block_entry block_entry = {
+       .cb = tc_indr_block_get_and_cmd,
+       .list = LIST_HEAD_INIT(block_entry.list),
 };
 
 static int __init tc_filter_init(void)
@@ -3643,7 +3663,7 @@ static int __init tc_filter_init(void)
        if (err)
                goto err_register_pernet_subsys;
 
-       flow_indr_add_block_ing_cb(&block_ing_entry);
+       flow_indr_add_block_cb(&block_entry);
 
        rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_new_tfilter, NULL,
                      RTNL_FLAG_DOIT_UNLOCKED);
index c307ee1..0d125de 100644 (file)
@@ -56,8 +56,13 @@ struct fl_flow_key {
        struct flow_dissector_key_ip ip;
        struct flow_dissector_key_ip enc_ip;
        struct flow_dissector_key_enc_opts enc_opts;
-       struct flow_dissector_key_ports tp_min;
-       struct flow_dissector_key_ports tp_max;
+       union {
+               struct flow_dissector_key_ports tp;
+               struct {
+                       struct flow_dissector_key_ports tp_min;
+                       struct flow_dissector_key_ports tp_max;
+               };
+       } tp_range;
        struct flow_dissector_key_ct ct;
 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
 
@@ -200,19 +205,19 @@ static bool fl_range_port_dst_cmp(struct cls_fl_filter *filter,
 {
        __be16 min_mask, max_mask, min_val, max_val;
 
-       min_mask = htons(filter->mask->key.tp_min.dst);
-       max_mask = htons(filter->mask->key.tp_max.dst);
-       min_val = htons(filter->key.tp_min.dst);
-       max_val = htons(filter->key.tp_max.dst);
+       min_mask = htons(filter->mask->key.tp_range.tp_min.dst);
+       max_mask = htons(filter->mask->key.tp_range.tp_max.dst);
+       min_val = htons(filter->key.tp_range.tp_min.dst);
+       max_val = htons(filter->key.tp_range.tp_max.dst);
 
        if (min_mask && max_mask) {
-               if (htons(key->tp.dst) < min_val ||
-                   htons(key->tp.dst) > max_val)
+               if (htons(key->tp_range.tp.dst) < min_val ||
+                   htons(key->tp_range.tp.dst) > max_val)
                        return false;
 
                /* skb does not have min and max values */
-               mkey->tp_min.dst = filter->mkey.tp_min.dst;
-               mkey->tp_max.dst = filter->mkey.tp_max.dst;
+               mkey->tp_range.tp_min.dst = filter->mkey.tp_range.tp_min.dst;
+               mkey->tp_range.tp_max.dst = filter->mkey.tp_range.tp_max.dst;
        }
        return true;
 }
@@ -223,19 +228,19 @@ static bool fl_range_port_src_cmp(struct cls_fl_filter *filter,
 {
        __be16 min_mask, max_mask, min_val, max_val;
 
-       min_mask = htons(filter->mask->key.tp_min.src);
-       max_mask = htons(filter->mask->key.tp_max.src);
-       min_val = htons(filter->key.tp_min.src);
-       max_val = htons(filter->key.tp_max.src);
+       min_mask = htons(filter->mask->key.tp_range.tp_min.src);
+       max_mask = htons(filter->mask->key.tp_range.tp_max.src);
+       min_val = htons(filter->key.tp_range.tp_min.src);
+       max_val = htons(filter->key.tp_range.tp_max.src);
 
        if (min_mask && max_mask) {
-               if (htons(key->tp.src) < min_val ||
-                   htons(key->tp.src) > max_val)
+               if (htons(key->tp_range.tp.src) < min_val ||
+                   htons(key->tp_range.tp.src) > max_val)
                        return false;
 
                /* skb does not have min and max values */
-               mkey->tp_min.src = filter->mkey.tp_min.src;
-               mkey->tp_max.src = filter->mkey.tp_max.src;
+               mkey->tp_range.tp_min.src = filter->mkey.tp_range.tp_min.src;
+               mkey->tp_range.tp_max.src = filter->mkey.tp_range.tp_max.src;
        }
        return true;
 }
@@ -734,23 +739,25 @@ static void fl_set_key_val(struct nlattr **tb,
 static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
                                 struct fl_flow_key *mask)
 {
-       fl_set_key_val(tb, &key->tp_min.dst,
-                      TCA_FLOWER_KEY_PORT_DST_MIN, &mask->tp_min.dst,
-                      TCA_FLOWER_UNSPEC, sizeof(key->tp_min.dst));
-       fl_set_key_val(tb, &key->tp_max.dst,
-                      TCA_FLOWER_KEY_PORT_DST_MAX, &mask->tp_max.dst,
-                      TCA_FLOWER_UNSPEC, sizeof(key->tp_max.dst));
-       fl_set_key_val(tb, &key->tp_min.src,
-                      TCA_FLOWER_KEY_PORT_SRC_MIN, &mask->tp_min.src,
-                      TCA_FLOWER_UNSPEC, sizeof(key->tp_min.src));
-       fl_set_key_val(tb, &key->tp_max.src,
-                      TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_max.src,
-                      TCA_FLOWER_UNSPEC, sizeof(key->tp_max.src));
-
-       if ((mask->tp_min.dst && mask->tp_max.dst &&
-            htons(key->tp_max.dst) <= htons(key->tp_min.dst)) ||
-            (mask->tp_min.src && mask->tp_max.src &&
-             htons(key->tp_max.src) <= htons(key->tp_min.src)))
+       fl_set_key_val(tb, &key->tp_range.tp_min.dst,
+                      TCA_FLOWER_KEY_PORT_DST_MIN, &mask->tp_range.tp_min.dst,
+                      TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_min.dst));
+       fl_set_key_val(tb, &key->tp_range.tp_max.dst,
+                      TCA_FLOWER_KEY_PORT_DST_MAX, &mask->tp_range.tp_max.dst,
+                      TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.dst));
+       fl_set_key_val(tb, &key->tp_range.tp_min.src,
+                      TCA_FLOWER_KEY_PORT_SRC_MIN, &mask->tp_range.tp_min.src,
+                      TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_min.src));
+       fl_set_key_val(tb, &key->tp_range.tp_max.src,
+                      TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src,
+                      TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src));
+
+       if ((mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst &&
+            htons(key->tp_range.tp_max.dst) <=
+                htons(key->tp_range.tp_min.dst)) ||
+           (mask->tp_range.tp_min.src && mask->tp_range.tp_max.src &&
+            htons(key->tp_range.tp_max.src) <=
+                htons(key->tp_range.tp_min.src)))
                return -EINVAL;
 
        return 0;
@@ -1474,7 +1481,7 @@ static int fl_init_mask_hashtable(struct fl_flow_mask *mask)
 }
 
 #define FL_KEY_MEMBER_OFFSET(member) offsetof(struct fl_flow_key, member)
-#define FL_KEY_MEMBER_SIZE(member) FIELD_SIZEOF(struct fl_flow_key, member)
+#define FL_KEY_MEMBER_SIZE(member) sizeof_field(struct fl_flow_key, member)
 
 #define FL_KEY_IS_MASKED(mask, member)                                         \
        memchr_inv(((char *)mask) + FL_KEY_MEMBER_OFFSET(member),               \
@@ -1509,9 +1516,10 @@ static void fl_init_dissector(struct flow_dissector *dissector,
                             FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4);
        FL_KEY_SET_IF_MASKED(mask, keys, cnt,
                             FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6);
-       if (FL_KEY_IS_MASKED(mask, tp) ||
-           FL_KEY_IS_MASKED(mask, tp_min) || FL_KEY_IS_MASKED(mask, tp_max))
-               FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_PORTS, tp);
+       FL_KEY_SET_IF_MASKED(mask, keys, cnt,
+                            FLOW_DISSECTOR_KEY_PORTS, tp);
+       FL_KEY_SET_IF_MASKED(mask, keys, cnt,
+                            FLOW_DISSECTOR_KEY_PORTS_RANGE, tp_range);
        FL_KEY_SET_IF_MASKED(mask, keys, cnt,
                             FLOW_DISSECTOR_KEY_IP, ip);
        FL_KEY_SET_IF_MASKED(mask, keys, cnt,
@@ -1560,8 +1568,10 @@ static struct fl_flow_mask *fl_create_new_mask(struct cls_fl_head *head,
 
        fl_mask_copy(newmask, mask);
 
-       if ((newmask->key.tp_min.dst && newmask->key.tp_max.dst) ||
-           (newmask->key.tp_min.src && newmask->key.tp_max.src))
+       if ((newmask->key.tp_range.tp_min.dst &&
+            newmask->key.tp_range.tp_max.dst) ||
+           (newmask->key.tp_range.tp_min.src &&
+            newmask->key.tp_range.tp_max.src))
                newmask->flags |= TCA_FLOWER_MASK_FLAGS_RANGE;
 
        err = fl_init_mask_hashtable(newmask);
@@ -2159,18 +2169,22 @@ static int fl_dump_key_val(struct sk_buff *skb,
 static int fl_dump_key_port_range(struct sk_buff *skb, struct fl_flow_key *key,
                                  struct fl_flow_key *mask)
 {
-       if (fl_dump_key_val(skb, &key->tp_min.dst, TCA_FLOWER_KEY_PORT_DST_MIN,
-                           &mask->tp_min.dst, TCA_FLOWER_UNSPEC,
-                           sizeof(key->tp_min.dst)) ||
-           fl_dump_key_val(skb, &key->tp_max.dst, TCA_FLOWER_KEY_PORT_DST_MAX,
-                           &mask->tp_max.dst, TCA_FLOWER_UNSPEC,
-                           sizeof(key->tp_max.dst)) ||
-           fl_dump_key_val(skb, &key->tp_min.src, TCA_FLOWER_KEY_PORT_SRC_MIN,
-                           &mask->tp_min.src, TCA_FLOWER_UNSPEC,
-                           sizeof(key->tp_min.src)) ||
-           fl_dump_key_val(skb, &key->tp_max.src, TCA_FLOWER_KEY_PORT_SRC_MAX,
-                           &mask->tp_max.src, TCA_FLOWER_UNSPEC,
-                           sizeof(key->tp_max.src)))
+       if (fl_dump_key_val(skb, &key->tp_range.tp_min.dst,
+                           TCA_FLOWER_KEY_PORT_DST_MIN,
+                           &mask->tp_range.tp_min.dst, TCA_FLOWER_UNSPEC,
+                           sizeof(key->tp_range.tp_min.dst)) ||
+           fl_dump_key_val(skb, &key->tp_range.tp_max.dst,
+                           TCA_FLOWER_KEY_PORT_DST_MAX,
+                           &mask->tp_range.tp_max.dst, TCA_FLOWER_UNSPEC,
+                           sizeof(key->tp_range.tp_max.dst)) ||
+           fl_dump_key_val(skb, &key->tp_range.tp_min.src,
+                           TCA_FLOWER_KEY_PORT_SRC_MIN,
+                           &mask->tp_range.tp_min.src, TCA_FLOWER_UNSPEC,
+                           sizeof(key->tp_range.tp_min.src)) ||
+           fl_dump_key_val(skb, &key->tp_range.tp_max.src,
+                           TCA_FLOWER_KEY_PORT_SRC_MAX,
+                           &mask->tp_range.tp_max.src, TCA_FLOWER_UNSPEC,
+                           sizeof(key->tp_range.tp_max.src)))
                return -1;
 
        return 0;
index 53a80bc..e0f4040 100644 (file)
@@ -2184,6 +2184,7 @@ static const struct nla_policy cake_policy[TCA_CAKE_MAX + 1] = {
        [TCA_CAKE_MPU]           = { .type = NLA_U32 },
        [TCA_CAKE_INGRESS]       = { .type = NLA_U32 },
        [TCA_CAKE_ACK_FILTER]    = { .type = NLA_U32 },
+       [TCA_CAKE_SPLIT_GSO]     = { .type = NLA_U32 },
        [TCA_CAKE_FWMARK]        = { .type = NLA_U32 },
 };
 
index 278c0b2..e79f1af 100644 (file)
@@ -153,6 +153,7 @@ static int mq_dump(struct Qdisc *sch, struct sk_buff *skb)
                        __gnet_stats_copy_queue(&sch->qstats,
                                                qdisc->cpu_qstats,
                                                &qdisc->qstats, qlen);
+                       sch->q.qlen             += qlen;
                } else {
                        sch->q.qlen             += qdisc->q.qlen;
                        sch->bstats.bytes       += qdisc->bstats.bytes;
index 0d0113a..8766ab5 100644 (file)
@@ -411,6 +411,7 @@ static int mqprio_dump(struct Qdisc *sch, struct sk_buff *skb)
                        __gnet_stats_copy_queue(&sch->qstats,
                                                qdisc->cpu_qstats,
                                                &qdisc->qstats, qlen);
+                       sch->q.qlen             += qlen;
                } else {
                        sch->q.qlen             += qdisc->q.qlen;
                        sch->bstats.bytes       += qdisc->bstats.bytes;
@@ -433,7 +434,7 @@ static int mqprio_dump(struct Qdisc *sch, struct sk_buff *skb)
                opt.offset[tc] = dev->tc_to_txq[tc].offset;
        }
 
-       if (nla_put(skb, TCA_OPTIONS, NLA_ALIGN(sizeof(opt)), &opt))
+       if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
                goto nla_put_failure;
 
        if ((priv->flags & TC_MQPRIO_F_MODE) &&
index dd860fe..bc734cf 100644 (file)
@@ -275,7 +275,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
        final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
        rcu_read_unlock();
 
-       dst = ip6_dst_lookup_flow(sk, fl6, final_p);
+       dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
        if (!asoc || saddr)
                goto out;
 
@@ -328,7 +328,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
                fl6->saddr = laddr->a.v6.sin6_addr;
                fl6->fl6_sport = laddr->a.v6.sin6_port;
                final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
-               bdst = ip6_dst_lookup_flow(sk, fl6, final_p);
+               bdst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
 
                if (IS_ERR(bdst))
                        continue;
index ea28cbb..5062321 100644 (file)
@@ -957,7 +957,7 @@ static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
                             .msg_iocb = iocb};
        ssize_t res;
 
-       if (file->f_flags & O_NONBLOCK)
+       if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
                msg.msg_flags = MSG_DONTWAIT;
 
        if (iocb->ki_pos != 0)
@@ -982,7 +982,7 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (iocb->ki_pos != 0)
                return -ESPIPE;
 
-       if (file->f_flags & O_NONBLOCK)
+       if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
                msg.msg_flags = MSG_DONTWAIT;
 
        if (sock->type == SOCK_SEQPACKET)
@@ -1826,26 +1826,22 @@ SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  *     include the -EINPROGRESS status for such sockets.
  */
 
-int __sys_connect_file(struct file *file, struct sockaddr __user *uservaddr,
+int __sys_connect_file(struct file *file, struct sockaddr_storage *address,
                       int addrlen, int file_flags)
 {
        struct socket *sock;
-       struct sockaddr_storage address;
        int err;
 
        sock = sock_from_file(file, &err);
        if (!sock)
                goto out;
-       err = move_addr_to_kernel(uservaddr, addrlen, &address);
-       if (err < 0)
-               goto out;
 
        err =
-           security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
+           security_socket_connect(sock, (struct sockaddr *)address, addrlen);
        if (err)
                goto out;
 
-       err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen,
+       err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen,
                                 sock->file->f_flags | file_flags);
 out:
        return err;
@@ -1858,7 +1854,11 @@ int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
 
        f = fdget(fd);
        if (f.file) {
-               ret = __sys_connect_file(f.file, uservaddr, addrlen, 0);
+               struct sockaddr_storage address;
+
+               ret = move_addr_to_kernel(uservaddr, addrlen, &address);
+               if (!ret)
+                       ret = __sys_connect_file(f.file, &address, addrlen, 0);
                if (f.flags)
                        fput(f.file);
        }
@@ -2346,9 +2346,9 @@ out:
        return err;
 }
 
-static int sendmsg_copy_msghdr(struct msghdr *msg,
-                              struct user_msghdr __user *umsg, unsigned flags,
-                              struct iovec **iov)
+int sendmsg_copy_msghdr(struct msghdr *msg,
+                       struct user_msghdr __user *umsg, unsigned flags,
+                       struct iovec **iov)
 {
        int err;
 
@@ -2390,27 +2390,14 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
 /*
  *     BSD sendmsg interface
  */
-long __sys_sendmsg_sock(struct socket *sock, struct user_msghdr __user *umsg,
+long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
                        unsigned int flags)
 {
-       struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
-       struct sockaddr_storage address;
-       struct msghdr msg = { .msg_name = &address };
-       ssize_t err;
-
-       err = sendmsg_copy_msghdr(&msg, umsg, flags, &iov);
-       if (err)
-               return err;
        /* disallow ancillary data requests from this path */
-       if (msg.msg_control || msg.msg_controllen) {
-               err = -EINVAL;
-               goto out;
-       }
+       if (msg->msg_control || msg->msg_controllen)
+               return -EINVAL;
 
-       err = ____sys_sendmsg(sock, &msg, flags, NULL, 0);
-out:
-       kfree(iov);
-       return err;
+       return ____sys_sendmsg(sock, msg, flags, NULL, 0);
 }
 
 long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
@@ -2516,10 +2503,10 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
        return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
 }
 
-static int recvmsg_copy_msghdr(struct msghdr *msg,
-                              struct user_msghdr __user *umsg, unsigned flags,
-                              struct sockaddr __user **uaddr,
-                              struct iovec **iov)
+int recvmsg_copy_msghdr(struct msghdr *msg,
+                       struct user_msghdr __user *umsg, unsigned flags,
+                       struct sockaddr __user **uaddr,
+                       struct iovec **iov)
 {
        ssize_t err;
 
@@ -2559,7 +2546,12 @@ static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys,
 
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
-       err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, flags);
+
+       if (unlikely(nosec))
+               err = sock_recvmsg_nosec(sock, msg_sys, flags);
+       else
+               err = sock_recvmsg(sock, msg_sys, flags);
+
        if (err < 0)
                goto out;
        len = err;
@@ -2609,28 +2601,15 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
  *     BSD recvmsg interface
  */
 
-long __sys_recvmsg_sock(struct socket *sock, struct user_msghdr __user *umsg,
-                       unsigned int flags)
+long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
+                       struct user_msghdr __user *umsg,
+                       struct sockaddr __user *uaddr, unsigned int flags)
 {
-       struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
-       struct sockaddr_storage address;
-       struct msghdr msg = { .msg_name = &address };
-       struct sockaddr __user *uaddr;
-       ssize_t err;
-
-       err = recvmsg_copy_msghdr(&msg, umsg, flags, &uaddr, &iov);
-       if (err)
-               return err;
        /* disallow ancillary data requests from this path */
-       if (msg.msg_control || msg.msg_controllen) {
-               err = -EINVAL;
-               goto out;
-       }
+       if (msg->msg_control || msg->msg_controllen)
+               return -EINVAL;
 
-       err = ____sys_recvmsg(sock, &msg, umsg, uaddr, flags, 0);
-out:
-       kfree(iov);
-       return err;
+       return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0);
 }
 
 long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
index 8206009..30b7de6 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/gss_api.h>
 #include <linux/sunrpc/clnt.h>
+#include <trace/events/rpcgss.h>
 
 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
@@ -158,7 +159,6 @@ struct gss_api_mech *gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
 
        if (sprint_oid(obj->data, obj->len, buf, sizeof(buf)) < 0)
                return NULL;
-       dprintk("RPC:       %s(%s)\n", __func__, buf);
        request_module("rpc-auth-gss-%s", buf);
 
        rcu_read_lock();
@@ -172,6 +172,8 @@ struct gss_api_mech *gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
                }
        }
        rcu_read_unlock();
+       if (!gm)
+               trace_rpcgss_oid_to_mech(buf);
        return gm;
 }
 
index 8be2f20..c62d1f1 100644 (file)
@@ -49,6 +49,9 @@
 #include <linux/sunrpc/svcauth.h>
 #include <linux/sunrpc/svcauth_gss.h>
 #include <linux/sunrpc/cache.h>
+
+#include <trace/events/rpcgss.h>
+
 #include "gss_rpc_upcall.h"
 
 
@@ -1075,24 +1078,32 @@ gss_read_verf(struct rpc_gss_wire_cred *gc,
        return 0;
 }
 
-/* Ok this is really heavily depending on a set of semantics in
- * how rqstp is set up by svc_recv and pages laid down by the
- * server when reading a request. We are basically guaranteed that
- * the token lays all down linearly across a set of pages, starting
- * at iov_base in rq_arg.head[0] which happens to be the first of a
- * set of pages stored in rq_pages[].
- * rq_arg.head[0].iov_base will provide us the page_base to pass
- * to the upcall.
- */
-static inline int
-gss_read_proxy_verf(struct svc_rqst *rqstp,
-                   struct rpc_gss_wire_cred *gc, __be32 *authp,
-                   struct xdr_netobj *in_handle,
-                   struct gssp_in_token *in_token)
+static void gss_free_in_token_pages(struct gssp_in_token *in_token)
 {
-       struct kvec *argv = &rqstp->rq_arg.head[0];
        u32 inlen;
-       int res;
+       int i;
+
+       i = 0;
+       inlen = in_token->page_len;
+       while (inlen) {
+               if (in_token->pages[i])
+                       put_page(in_token->pages[i]);
+               inlen -= inlen > PAGE_SIZE ? PAGE_SIZE : inlen;
+       }
+
+       kfree(in_token->pages);
+       in_token->pages = NULL;
+}
+
+static int gss_read_proxy_verf(struct svc_rqst *rqstp,
+                              struct rpc_gss_wire_cred *gc, __be32 *authp,
+                              struct xdr_netobj *in_handle,
+                              struct gssp_in_token *in_token)
+{
+       struct kvec *argv = &rqstp->rq_arg.head[0];
+       unsigned int page_base, length;
+       int pages, i, res;
+       size_t inlen;
 
        res = gss_read_common_verf(gc, argv, authp, in_handle);
        if (res)
@@ -1102,10 +1113,36 @@ gss_read_proxy_verf(struct svc_rqst *rqstp,
        if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
                return SVC_DENIED;
 
-       in_token->pages = rqstp->rq_pages;
-       in_token->page_base = (ulong)argv->iov_base & ~PAGE_MASK;
+       pages = DIV_ROUND_UP(inlen, PAGE_SIZE);
+       in_token->pages = kcalloc(pages, sizeof(struct page *), GFP_KERNEL);
+       if (!in_token->pages)
+               return SVC_DENIED;
+       in_token->page_base = 0;
        in_token->page_len = inlen;
+       for (i = 0; i < pages; i++) {
+               in_token->pages[i] = alloc_page(GFP_KERNEL);
+               if (!in_token->pages[i]) {
+                       gss_free_in_token_pages(in_token);
+                       return SVC_DENIED;
+               }
+       }
 
+       length = min_t(unsigned int, inlen, argv->iov_len);
+       memcpy(page_address(in_token->pages[0]), argv->iov_base, length);
+       inlen -= length;
+
+       i = 1;
+       page_base = rqstp->rq_arg.page_base;
+       while (inlen) {
+               length = min_t(unsigned int, inlen, PAGE_SIZE);
+               memcpy(page_address(in_token->pages[i]),
+                      page_address(rqstp->rq_arg.pages[i]) + page_base,
+                      length);
+
+               inlen -= length;
+               page_base = 0;
+               i++;
+       }
        return 0;
 }
 
@@ -1270,9 +1307,8 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp,
        if (status)
                goto out;
 
-       dprintk("RPC:       svcauth_gss: gss major status = %d "
-                       "minor status = %d\n",
-                       ud.major_status, ud.minor_status);
+       trace_rpcgss_accept_upcall(rqstp->rq_xid, ud.major_status,
+                                  ud.minor_status);
 
        switch (ud.major_status) {
        case GSS_S_CONTINUE_NEEDED:
@@ -1280,8 +1316,11 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp,
                break;
        case GSS_S_COMPLETE:
                status = gss_proxy_save_rsc(sn->rsc_cache, &ud, &handle);
-               if (status)
+               if (status) {
+                       pr_info("%s: gss_proxy_save_rsc failed (%d)\n",
+                               __func__, status);
                        goto out;
+               }
                cli_handle.data = (u8 *)&handle;
                cli_handle.len = sizeof(handle);
                break;
@@ -1292,15 +1331,20 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp,
 
        /* Got an answer to the upcall; use it: */
        if (gss_write_init_verf(sn->rsc_cache, rqstp,
-                               &cli_handle, &ud.major_status))
+                               &cli_handle, &ud.major_status)) {
+               pr_info("%s: gss_write_init_verf failed\n", __func__);
                goto out;
+       }
        if (gss_write_resv(resv, PAGE_SIZE,
                           &cli_handle, &ud.out_token,
-                          ud.major_status, ud.minor_status))
+                          ud.major_status, ud.minor_status)) {
+               pr_info("%s: gss_write_resv failed\n", __func__);
                goto out;
+       }
 
        ret = SVC_COMPLETE;
 out:
+       gss_free_in_token_pages(&ud.in_token);
        gssp_free_upcall_data(&ud);
        return ret;
 }
index a349094..f740cb5 100644 (file)
@@ -53,9 +53,6 @@ static void cache_init(struct cache_head *h, struct cache_detail *detail)
        h->last_refresh = now;
 }
 
-static inline int cache_is_valid(struct cache_head *h);
-static void cache_fresh_locked(struct cache_head *head, time_t expiry,
-                               struct cache_detail *detail);
 static void cache_fresh_unlocked(struct cache_head *head,
                                struct cache_detail *detail);
 
@@ -105,9 +102,6 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
                        if (cache_is_expired(detail, tmp)) {
                                hlist_del_init_rcu(&tmp->cache_list);
                                detail->entries --;
-                               if (cache_is_valid(tmp) == -EAGAIN)
-                                       set_bit(CACHE_NEGATIVE, &tmp->flags);
-                               cache_fresh_locked(tmp, 0, detail);
                                freeme = tmp;
                                break;
                        }
index f7f7856..a337976 100644 (file)
@@ -591,6 +591,9 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
        xprt->resvport = 1;
        if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
                xprt->resvport = 0;
+       xprt->reuseport = 0;
+       if (args->flags & RPC_CLNT_CREATE_REUSEPORT)
+               xprt->reuseport = 1;
 
        clnt = rpc_create_xprt(args, xprt);
        if (IS_ERR(clnt) || args->nconnect <= 1)
@@ -1676,8 +1679,6 @@ call_reserveresult(struct rpc_task *task)
                        return;
                }
 
-               printk(KERN_ERR "%s: status=%d, but no request slot, exiting\n",
-                               __func__, status);
                rpc_call_rpcerror(task, -EIO);
                return;
        }
@@ -1686,11 +1687,8 @@ call_reserveresult(struct rpc_task *task)
         * Even though there was an error, we may have acquired
         * a request slot somehow.  Make sure not to leak it.
         */
-       if (task->tk_rqstp) {
-               printk(KERN_ERR "%s: status=%d, request allocated anyway\n",
-                               __func__, status);
+       if (task->tk_rqstp)
                xprt_release(task);
-       }
 
        switch (status) {
        case -ENOMEM:
@@ -1699,14 +1697,9 @@ call_reserveresult(struct rpc_task *task)
        case -EAGAIN:   /* woken up; retry */
                task->tk_action = call_retry_reserve;
                return;
-       case -EIO:      /* probably a shutdown */
-               break;
        default:
-               printk(KERN_ERR "%s: unrecognized error %d, exiting\n",
-                               __func__, status);
-               break;
+               rpc_call_rpcerror(task, status);
        }
-       rpc_call_rpcerror(task, status);
 }
 
 /*
@@ -2906,7 +2899,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
        struct rpc_xprt *xprt;
        unsigned long connect_timeout;
        unsigned long reconnect_timeout;
-       unsigned char resvport;
+       unsigned char resvport, reuseport;
        int ret = 0;
 
        rcu_read_lock();
@@ -2918,6 +2911,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
                return -EAGAIN;
        }
        resvport = xprt->resvport;
+       reuseport = xprt->reuseport;
        connect_timeout = xprt->connect_timeout;
        reconnect_timeout = xprt->max_reconnect_timeout;
        rcu_read_unlock();
@@ -2928,6 +2922,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
                goto out_put_switch;
        }
        xprt->resvport = resvport;
+       xprt->reuseport = reuseport;
        if (xprt->ops->set_connect_timeout != NULL)
                xprt->ops->set_connect_timeout(xprt,
                                connect_timeout,
index b71a39d..39e14d5 100644 (file)
@@ -51,7 +51,7 @@ static BLOCKING_NOTIFIER_HEAD(rpc_pipefs_notifier_list);
 
 int rpc_pipefs_notifier_register(struct notifier_block *nb)
 {
-       return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb);
+       return blocking_notifier_chain_register(&rpc_pipefs_notifier_list, nb);
 }
 EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_register);
 
index 360afe1..9c79548 100644 (file)
@@ -260,7 +260,7 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c
        rpc_reset_waitqueue_priority(queue);
        queue->qlen = 0;
        queue->timer_list.expires = 0;
-       INIT_DEFERRABLE_WORK(&queue->timer_list.dwork, __rpc_queue_timer_fn);
+       INIT_DELAYED_WORK(&queue->timer_list.dwork, __rpc_queue_timer_fn);
        INIT_LIST_HEAD(&queue->timer_list.list);
        rpc_assign_waitqueue_name(queue, qname);
 }
@@ -824,6 +824,7 @@ rpc_reset_task_statistics(struct rpc_task *task)
  */
 void rpc_exit_task(struct rpc_task *task)
 {
+       trace_rpc_task_end(task, task->tk_action);
        task->tk_action = NULL;
        if (task->tk_ops->rpc_count_stats)
                task->tk_ops->rpc_count_stats(task, task->tk_calldata);
index d11b705..187dd4e 100644 (file)
@@ -1337,6 +1337,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
                auth_stat = rpc_autherr_badcred;
                auth_res = progp->pg_authenticate(rqstp);
        }
+       if (auth_res != SVC_OK)
+               trace_svc_authenticate(rqstp, auth_res, auth_stat);
        switch (auth_res) {
        case SVC_OK:
                break;
index 550b214..552617e 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/err.h>
 #include <linux/hash.h>
 
+#include <trace/events/sunrpc.h>
+
 #define RPCDBG_FACILITY        RPCDBG_AUTH
 
 
index 14ba9e7..f3104be 100644 (file)
@@ -436,13 +436,12 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
 }
 
 /**
- * xdr_shrink_pagelen
+ * xdr_shrink_pagelen - shrinks buf->pages by up to @len bytes
  * @buf: xdr_buf
  * @len: bytes to remove from buf->pages
  *
- * Shrinks XDR buffer's page array buf->pages by
- * 'len' bytes. The extra data is not lost, but is instead
- * moved into the tail.
+ * The extra data is not lost, but is instead moved into buf->tail.
+ * Returns the actual number of bytes moved.
  */
 static unsigned int
 xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
@@ -455,8 +454,8 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
 
        result = 0;
        tail = buf->tail;
-       BUG_ON (len > pglen);
-
+       if (len > buf->page_len)
+               len = buf-> page_len;
        tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;
 
        /* Shift the tail first */
index 41df4c5..1aafe8d 100644 (file)
@@ -205,20 +205,20 @@ int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
 
        if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
                if (task == xprt->snd_task)
-                       return 1;
+                       goto out_locked;
                goto out_sleep;
        }
        if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
                goto out_unlock;
        xprt->snd_task = task;
 
+out_locked:
+       trace_xprt_reserve_xprt(xprt, task);
        return 1;
 
 out_unlock:
        xprt_clear_locked(xprt);
 out_sleep:
-       dprintk("RPC: %5u failed to lock transport %p\n",
-                       task->tk_pid, xprt);
        task->tk_status = -EAGAIN;
        if  (RPC_IS_SOFT(task))
                rpc_sleep_on_timeout(&xprt->sending, task, NULL,
@@ -269,23 +269,22 @@ int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
 
        if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
                if (task == xprt->snd_task)
-                       return 1;
+                       goto out_locked;
                goto out_sleep;
        }
        if (req == NULL) {
                xprt->snd_task = task;
-               return 1;
+               goto out_locked;
        }
        if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
                goto out_unlock;
        if (!xprt_need_congestion_window_wait(xprt)) {
                xprt->snd_task = task;
-               return 1;
+               goto out_locked;
        }
 out_unlock:
        xprt_clear_locked(xprt);
 out_sleep:
-       dprintk("RPC: %5u failed to lock transport %p\n", task->tk_pid, xprt);
        task->tk_status = -EAGAIN;
        if (RPC_IS_SOFT(task))
                rpc_sleep_on_timeout(&xprt->sending, task, NULL,
@@ -293,6 +292,9 @@ out_sleep:
        else
                rpc_sleep_on(&xprt->sending, task, NULL);
        return 0;
+out_locked:
+       trace_xprt_reserve_cong(xprt, task);
+       return 1;
 }
 EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);
 
@@ -357,6 +359,7 @@ void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
                xprt_clear_locked(xprt);
                __xprt_lock_write_next(xprt);
        }
+       trace_xprt_release_xprt(xprt, task);
 }
 EXPORT_SYMBOL_GPL(xprt_release_xprt);
 
@@ -374,6 +377,7 @@ void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
                xprt_clear_locked(xprt);
                __xprt_lock_write_next_cong(xprt);
        }
+       trace_xprt_release_cong(xprt, task);
 }
 EXPORT_SYMBOL_GPL(xprt_release_xprt_cong);
 
@@ -395,8 +399,7 @@ __xprt_get_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
 {
        if (req->rq_cong)
                return 1;
-       dprintk("RPC: %5u xprt_cwnd_limited cong = %lu cwnd = %lu\n",
-                       req->rq_task->tk_pid, xprt->cong, xprt->cwnd);
+       trace_xprt_get_cong(xprt, req->rq_task);
        if (RPCXPRT_CONGESTED(xprt)) {
                xprt_set_congestion_window_wait(xprt);
                return 0;
@@ -418,6 +421,7 @@ __xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
        req->rq_cong = 0;
        xprt->cong -= RPC_CWNDSCALE;
        xprt_test_and_clear_congestion_window_wait(xprt);
+       trace_xprt_put_cong(xprt, req->rq_task);
        __xprt_lock_write_next_cong(xprt);
 }
 
index b458bf5..9d02eae 100644 (file)
@@ -79,7 +79,7 @@ static int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst)
        *p = xdr_zero;
 
        if (rpcrdma_prepare_send_sges(r_xprt, req, RPCRDMA_HDRLEN_MIN,
-                                     &rqst->rq_snd_buf, rpcrdma_noch))
+                                     &rqst->rq_snd_buf, rpcrdma_noch_pullup))
                return -EIO;
 
        trace_xprtrdma_cb_reply(rqst);
index 30065a2..523722b 100644 (file)
@@ -36,8 +36,8 @@
  * connect worker from running concurrently.
  *
  * When the underlying transport disconnects, MRs that are in flight
- * are flushed and are likely unusable. Thus all flushed MRs are
- * destroyed. New MRs are created on demand.
+ * are flushed and are likely unusable. Thus all MRs are destroyed.
+ * New MRs are created on demand.
  */
 
 #include <linux/sunrpc/rpc_rdma.h>
@@ -88,8 +88,10 @@ void frwr_release_mr(struct rpcrdma_mr *mr)
        kfree(mr);
 }
 
-static void frwr_mr_recycle(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)
+static void frwr_mr_recycle(struct rpcrdma_mr *mr)
 {
+       struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
+
        trace_xprtrdma_mr_recycle(mr);
 
        if (mr->mr_dir != DMA_NONE) {
@@ -107,32 +109,6 @@ static void frwr_mr_recycle(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)
        frwr_release_mr(mr);
 }
 
-/* MRs are dynamically allocated, so simply clean up and release the MR.
- * A replacement MR will subsequently be allocated on demand.
- */
-static void
-frwr_mr_recycle_worker(struct work_struct *work)
-{
-       struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr,
-                                            mr_recycle);
-
-       frwr_mr_recycle(mr->mr_xprt, mr);
-}
-
-/* frwr_recycle - Discard MRs
- * @req: request to reset
- *
- * Used after a reconnect. These MRs could be in flight, we can't
- * tell. Safe thing to do is release them.
- */
-void frwr_recycle(struct rpcrdma_req *req)
-{
-       struct rpcrdma_mr *mr;
-
-       while ((mr = rpcrdma_mr_pop(&req->rl_registered)))
-               frwr_mr_recycle(mr->mr_xprt, mr);
-}
-
 /* frwr_reset - Place MRs back on the free list
  * @req: request to reset
  *
@@ -166,9 +142,6 @@ int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
        struct ib_mr *frmr;
        int rc;
 
-       /* NB: ib_alloc_mr and device drivers typically allocate
-        *     memory with GFP_KERNEL.
-        */
        frmr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, depth);
        if (IS_ERR(frmr))
                goto out_mr_err;
@@ -180,7 +153,6 @@ int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
        mr->frwr.fr_mr = frmr;
        mr->mr_dir = DMA_NONE;
        INIT_LIST_HEAD(&mr->mr_list);
-       INIT_WORK(&mr->mr_recycle, frwr_mr_recycle_worker);
        init_completion(&mr->frwr.fr_linv_done);
 
        sg_init_table(sg, depth);
@@ -424,7 +396,7 @@ int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
        struct ib_send_wr *post_wr;
        struct rpcrdma_mr *mr;
 
-       post_wr = &req->rl_sendctx->sc_wr;
+       post_wr = &req->rl_wr;
        list_for_each_entry(mr, &req->rl_registered, mr_list) {
                struct rpcrdma_frwr *frwr;
 
@@ -440,9 +412,6 @@ int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
                post_wr = &frwr->fr_regwr.wr;
        }
 
-       /* If ib_post_send fails, the next ->send_request for
-        * @req will queue these MRs for recovery.
-        */
        return ib_post_send(ia->ri_id->qp, post_wr, NULL);
 }
 
@@ -468,7 +437,7 @@ void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs)
 static void __frwr_release_mr(struct ib_wc *wc, struct rpcrdma_mr *mr)
 {
        if (wc->status != IB_WC_SUCCESS)
-               rpcrdma_mr_recycle(mr);
+               frwr_mr_recycle(mr);
        else
                rpcrdma_mr_put(mr);
 }
@@ -570,7 +539,6 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         */
        bad_wr = NULL;
        rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);
-       trace_xprtrdma_post_send(req, rc);
 
        /* The final LOCAL_INV WR in the chain is supposed to
         * do the wake. If it was never posted, the wake will
@@ -583,6 +551,7 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
 
        /* Recycle MRs in the LOCAL_INV chain that did not get posted.
         */
+       trace_xprtrdma_post_linv(req, rc);
        while (bad_wr) {
                frwr = container_of(bad_wr, struct rpcrdma_frwr,
                                    fr_invwr);
@@ -590,7 +559,7 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
                bad_wr = bad_wr->next;
 
                list_del_init(&mr->mr_list);
-               rpcrdma_mr_recycle(mr);
+               frwr_mr_recycle(mr);
        }
 }
 
@@ -673,18 +642,18 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         */
        bad_wr = NULL;
        rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);
-       trace_xprtrdma_post_send(req, rc);
        if (!rc)
                return;
 
        /* Recycle MRs in the LOCAL_INV chain that did not get posted.
         */
+       trace_xprtrdma_post_linv(req, rc);
        while (bad_wr) {
                frwr = container_of(bad_wr, struct rpcrdma_frwr, fr_invwr);
                mr = container_of(frwr, struct rpcrdma_mr, frwr);
                bad_wr = bad_wr->next;
 
-               rpcrdma_mr_recycle(mr);
+               frwr_mr_recycle(mr);
        }
 
        /* The final LOCAL_INV WR in the chain is supposed to
index b86b5fd..aec3beb 100644 (file)
@@ -78,8 +78,6 @@ static unsigned int rpcrdma_max_call_header_size(unsigned int maxsegs)
        size += rpcrdma_segment_maxsz * sizeof(__be32);
        size += sizeof(__be32); /* list discriminator */
 
-       dprintk("RPC:       %s: max call header size = %u\n",
-               __func__, size);
        return size;
 }
 
@@ -100,8 +98,6 @@ static unsigned int rpcrdma_max_reply_header_size(unsigned int maxsegs)
        size += maxsegs * rpcrdma_segment_maxsz * sizeof(__be32);
        size += sizeof(__be32); /* list discriminator */
 
-       dprintk("RPC:       %s: max reply header size = %u\n",
-               __func__, size);
        return size;
 }
 
@@ -363,8 +359,7 @@ static struct rpcrdma_mr_seg *rpcrdma_mr_prepare(struct rpcrdma_xprt *r_xprt,
 out_getmr_err:
        trace_xprtrdma_nomrs(req);
        xprt_wait_for_buffer_space(&r_xprt->rx_xprt);
-       if (r_xprt->rx_ep.rep_connected != -ENODEV)
-               schedule_work(&r_xprt->rx_buf.rb_refresh_worker);
+       rpcrdma_mrs_refresh(r_xprt);
        return ERR_PTR(-EAGAIN);
 }
 
@@ -393,7 +388,7 @@ static int rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt,
        unsigned int pos;
        int nsegs;
 
-       if (rtype == rpcrdma_noch)
+       if (rtype == rpcrdma_noch_pullup || rtype == rpcrdma_noch_mapped)
                goto done;
 
        pos = rqst->rq_snd_buf.head[0].iov_len;
@@ -565,6 +560,7 @@ static void rpcrdma_sendctx_done(struct kref *kref)
  */
 void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)
 {
+       struct rpcrdma_regbuf *rb = sc->sc_req->rl_sendbuf;
        struct ib_sge *sge;
 
        if (!sc->sc_unmap_count)
@@ -576,7 +572,7 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)
         */
        for (sge = &sc->sc_sges[2]; sc->sc_unmap_count;
             ++sge, --sc->sc_unmap_count)
-               ib_dma_unmap_page(sc->sc_device, sge->addr, sge->length,
+               ib_dma_unmap_page(rdmab_device(rb), sge->addr, sge->length,
                                  DMA_TO_DEVICE);
 
        kref_put(&sc->sc_req->rl_kref, rpcrdma_sendctx_done);
@@ -589,149 +585,228 @@ static bool rpcrdma_prepare_hdr_sge(struct rpcrdma_xprt *r_xprt,
 {
        struct rpcrdma_sendctx *sc = req->rl_sendctx;
        struct rpcrdma_regbuf *rb = req->rl_rdmabuf;
-       struct ib_sge *sge = sc->sc_sges;
+       struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++];
 
        if (!rpcrdma_regbuf_dma_map(r_xprt, rb))
-               goto out_regbuf;
+               return false;
        sge->addr = rdmab_addr(rb);
        sge->length = len;
        sge->lkey = rdmab_lkey(rb);
 
        ib_dma_sync_single_for_device(rdmab_device(rb), sge->addr, sge->length,
                                      DMA_TO_DEVICE);
-       sc->sc_wr.num_sge++;
        return true;
-
-out_regbuf:
-       pr_err("rpcrdma: failed to DMA map a Send buffer\n");
-       return false;
 }
 
-/* Prepare the Send SGEs. The head and tail iovec, and each entry
- * in the page list, gets its own SGE.
+/* The head iovec is straightforward, as it is usually already
+ * DMA-mapped. Sync the content that has changed.
  */
-static bool rpcrdma_prepare_msg_sges(struct rpcrdma_xprt *r_xprt,
-                                    struct rpcrdma_req *req,
-                                    struct xdr_buf *xdr,
-                                    enum rpcrdma_chunktype rtype)
+static bool rpcrdma_prepare_head_iov(struct rpcrdma_xprt *r_xprt,
+                                    struct rpcrdma_req *req, unsigned int len)
 {
        struct rpcrdma_sendctx *sc = req->rl_sendctx;
-       unsigned int sge_no, page_base, len, remaining;
+       struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++];
        struct rpcrdma_regbuf *rb = req->rl_sendbuf;
-       struct ib_sge *sge = sc->sc_sges;
-       struct page *page, **ppages;
 
-       /* The head iovec is straightforward, as it is already
-        * DMA-mapped. Sync the content that has changed.
-        */
        if (!rpcrdma_regbuf_dma_map(r_xprt, rb))
-               goto out_regbuf;
-       sc->sc_device = rdmab_device(rb);
-       sge_no = 1;
-       sge[sge_no].addr = rdmab_addr(rb);
-       sge[sge_no].length = xdr->head[0].iov_len;
-       sge[sge_no].lkey = rdmab_lkey(rb);
-       ib_dma_sync_single_for_device(rdmab_device(rb), sge[sge_no].addr,
-                                     sge[sge_no].length, DMA_TO_DEVICE);
-
-       /* If there is a Read chunk, the page list is being handled
-        * via explicit RDMA, and thus is skipped here. However, the
-        * tail iovec may include an XDR pad for the page list, as
-        * well as additional content, and may not reside in the
-        * same page as the head iovec.
-        */
-       if (rtype == rpcrdma_readch) {
-               len = xdr->tail[0].iov_len;
+               return false;
 
-               /* Do not include the tail if it is only an XDR pad */
-               if (len < 4)
-                       goto out;
+       sge->addr = rdmab_addr(rb);
+       sge->length = len;
+       sge->lkey = rdmab_lkey(rb);
 
-               page = virt_to_page(xdr->tail[0].iov_base);
-               page_base = offset_in_page(xdr->tail[0].iov_base);
+       ib_dma_sync_single_for_device(rdmab_device(rb), sge->addr, sge->length,
+                                     DMA_TO_DEVICE);
+       return true;
+}
 
-               /* If the content in the page list is an odd length,
-                * xdr_write_pages() has added a pad at the beginning
-                * of the tail iovec. Force the tail's non-pad content
-                * to land at the next XDR position in the Send message.
-                */
-               page_base += len & 3;
-               len -= len & 3;
-               goto map_tail;
-       }
+/* If there is a page list present, DMA map and prepare an
+ * SGE for each page to be sent.
+ */
+static bool rpcrdma_prepare_pagelist(struct rpcrdma_req *req,
+                                    struct xdr_buf *xdr)
+{
+       struct rpcrdma_sendctx *sc = req->rl_sendctx;
+       struct rpcrdma_regbuf *rb = req->rl_sendbuf;
+       unsigned int page_base, len, remaining;
+       struct page **ppages;
+       struct ib_sge *sge;
 
-       /* If there is a page list present, temporarily DMA map
-        * and prepare an SGE for each page to be sent.
-        */
-       if (xdr->page_len) {
-               ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);
-               page_base = offset_in_page(xdr->page_base);
-               remaining = xdr->page_len;
-               while (remaining) {
-                       sge_no++;
-                       if (sge_no > RPCRDMA_MAX_SEND_SGES - 2)
-                               goto out_mapping_overflow;
-
-                       len = min_t(u32, PAGE_SIZE - page_base, remaining);
-                       sge[sge_no].addr =
-                               ib_dma_map_page(rdmab_device(rb), *ppages,
-                                               page_base, len, DMA_TO_DEVICE);
-                       if (ib_dma_mapping_error(rdmab_device(rb),
-                                                sge[sge_no].addr))
-                               goto out_mapping_err;
-                       sge[sge_no].length = len;
-                       sge[sge_no].lkey = rdmab_lkey(rb);
-
-                       sc->sc_unmap_count++;
-                       ppages++;
-                       remaining -= len;
-                       page_base = 0;
-               }
-       }
+       ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);
+       page_base = offset_in_page(xdr->page_base);
+       remaining = xdr->page_len;
+       while (remaining) {
+               sge = &sc->sc_sges[req->rl_wr.num_sge++];
+               len = min_t(unsigned int, PAGE_SIZE - page_base, remaining);
+               sge->addr = ib_dma_map_page(rdmab_device(rb), *ppages,
+                                           page_base, len, DMA_TO_DEVICE);
+               if (ib_dma_mapping_error(rdmab_device(rb), sge->addr))
+                       goto out_mapping_err;
 
-       /* The tail iovec is not always constructed in the same
-        * page where the head iovec resides (see, for example,
-        * gss_wrap_req_priv). To neatly accommodate that case,
-        * DMA map it separately.
-        */
-       if (xdr->tail[0].iov_len) {
-               page = virt_to_page(xdr->tail[0].iov_base);
-               page_base = offset_in_page(xdr->tail[0].iov_base);
-               len = xdr->tail[0].iov_len;
+               sge->length = len;
+               sge->lkey = rdmab_lkey(rb);
 
-map_tail:
-               sge_no++;
-               sge[sge_no].addr =
-                       ib_dma_map_page(rdmab_device(rb), page, page_base, len,
-                                       DMA_TO_DEVICE);
-               if (ib_dma_mapping_error(rdmab_device(rb), sge[sge_no].addr))
-                       goto out_mapping_err;
-               sge[sge_no].length = len;
-               sge[sge_no].lkey = rdmab_lkey(rb);
                sc->sc_unmap_count++;
+               ppages++;
+               remaining -= len;
+               page_base = 0;
        }
 
-out:
-       sc->sc_wr.num_sge += sge_no;
-       if (sc->sc_unmap_count)
-               kref_get(&req->rl_kref);
        return true;
 
-out_regbuf:
-       pr_err("rpcrdma: failed to DMA map a Send buffer\n");
+out_mapping_err:
+       trace_xprtrdma_dma_maperr(sge->addr);
        return false;
+}
 
-out_mapping_overflow:
-       rpcrdma_sendctx_unmap(sc);
-       pr_err("rpcrdma: too many Send SGEs (%u)\n", sge_no);
-       return false;
+/* The tail iovec may include an XDR pad for the page list,
+ * as well as additional content, and may not reside in the
+ * same page as the head iovec.
+ */
+static bool rpcrdma_prepare_tail_iov(struct rpcrdma_req *req,
+                                    struct xdr_buf *xdr,
+                                    unsigned int page_base, unsigned int len)
+{
+       struct rpcrdma_sendctx *sc = req->rl_sendctx;
+       struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++];
+       struct rpcrdma_regbuf *rb = req->rl_sendbuf;
+       struct page *page = virt_to_page(xdr->tail[0].iov_base);
+
+       sge->addr = ib_dma_map_page(rdmab_device(rb), page, page_base, len,
+                                   DMA_TO_DEVICE);
+       if (ib_dma_mapping_error(rdmab_device(rb), sge->addr))
+               goto out_mapping_err;
+
+       sge->length = len;
+       sge->lkey = rdmab_lkey(rb);
+       ++sc->sc_unmap_count;
+       return true;
 
 out_mapping_err:
-       rpcrdma_sendctx_unmap(sc);
-       trace_xprtrdma_dma_maperr(sge[sge_no].addr);
+       trace_xprtrdma_dma_maperr(sge->addr);
        return false;
 }
 
+/* Copy the tail to the end of the head buffer.
+ */
+static void rpcrdma_pullup_tail_iov(struct rpcrdma_xprt *r_xprt,
+                                   struct rpcrdma_req *req,
+                                   struct xdr_buf *xdr)
+{
+       unsigned char *dst;
+
+       dst = (unsigned char *)xdr->head[0].iov_base;
+       dst += xdr->head[0].iov_len + xdr->page_len;
+       memmove(dst, xdr->tail[0].iov_base, xdr->tail[0].iov_len);
+       r_xprt->rx_stats.pullup_copy_count += xdr->tail[0].iov_len;
+}
+
+/* Copy pagelist content into the head buffer.
+ */
+static void rpcrdma_pullup_pagelist(struct rpcrdma_xprt *r_xprt,
+                                   struct rpcrdma_req *req,
+                                   struct xdr_buf *xdr)
+{
+       unsigned int len, page_base, remaining;
+       struct page **ppages;
+       unsigned char *src, *dst;
+
+       dst = (unsigned char *)xdr->head[0].iov_base;
+       dst += xdr->head[0].iov_len;
+       ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);
+       page_base = offset_in_page(xdr->page_base);
+       remaining = xdr->page_len;
+       while (remaining) {
+               src = page_address(*ppages);
+               src += page_base;
+               len = min_t(unsigned int, PAGE_SIZE - page_base, remaining);
+               memcpy(dst, src, len);
+               r_xprt->rx_stats.pullup_copy_count += len;
+
+               ppages++;
+               dst += len;
+               remaining -= len;
+               page_base = 0;
+       }
+}
+
+/* Copy the contents of @xdr into @rl_sendbuf and DMA sync it.
+ * When the head, pagelist, and tail are small, a pull-up copy
+ * is considerably less costly than DMA mapping the components
+ * of @xdr.
+ *
+ * Assumptions:
+ *  - the caller has already verified that the total length
+ *    of the RPC Call body will fit into @rl_sendbuf.
+ */
+static bool rpcrdma_prepare_noch_pullup(struct rpcrdma_xprt *r_xprt,
+                                       struct rpcrdma_req *req,
+                                       struct xdr_buf *xdr)
+{
+       if (unlikely(xdr->tail[0].iov_len))
+               rpcrdma_pullup_tail_iov(r_xprt, req, xdr);
+
+       if (unlikely(xdr->page_len))
+               rpcrdma_pullup_pagelist(r_xprt, req, xdr);
+
+       /* The whole RPC message resides in the head iovec now */
+       return rpcrdma_prepare_head_iov(r_xprt, req, xdr->len);
+}
+
+static bool rpcrdma_prepare_noch_mapped(struct rpcrdma_xprt *r_xprt,
+                                       struct rpcrdma_req *req,
+                                       struct xdr_buf *xdr)
+{
+       struct kvec *tail = &xdr->tail[0];
+
+       if (!rpcrdma_prepare_head_iov(r_xprt, req, xdr->head[0].iov_len))
+               return false;
+       if (xdr->page_len)
+               if (!rpcrdma_prepare_pagelist(req, xdr))
+                       return false;
+       if (tail->iov_len)
+               if (!rpcrdma_prepare_tail_iov(req, xdr,
+                                             offset_in_page(tail->iov_base),
+                                             tail->iov_len))
+                       return false;
+
+       if (req->rl_sendctx->sc_unmap_count)
+               kref_get(&req->rl_kref);
+       return true;
+}
+
+static bool rpcrdma_prepare_readch(struct rpcrdma_xprt *r_xprt,
+                                  struct rpcrdma_req *req,
+                                  struct xdr_buf *xdr)
+{
+       if (!rpcrdma_prepare_head_iov(r_xprt, req, xdr->head[0].iov_len))
+               return false;
+
+       /* If there is a Read chunk, the page list is being handled
+        * via explicit RDMA, and thus is skipped here.
+        */
+
+       /* Do not include the tail if it is only an XDR pad */
+       if (xdr->tail[0].iov_len > 3) {
+               unsigned int page_base, len;
+
+               /* If the content in the page list is an odd length,
+                * xdr_write_pages() adds a pad at the beginning of
+                * the tail iovec. Force the tail's non-pad content to
+                * land at the next XDR position in the Send message.
+                */
+               page_base = offset_in_page(xdr->tail[0].iov_base);
+               len = xdr->tail[0].iov_len;
+               page_base += len & 3;
+               len -= len & 3;
+               if (!rpcrdma_prepare_tail_iov(req, xdr, page_base, len))
+                       return false;
+               kref_get(&req->rl_kref);
+       }
+
+       return true;
+}
+
 /**
  * rpcrdma_prepare_send_sges - Construct SGEs for a Send WR
  * @r_xprt: controlling transport
@@ -742,31 +817,53 @@ out_mapping_err:
  *
  * Returns 0 on success; otherwise a negative errno is returned.
  */
-int
-rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt,
-                         struct rpcrdma_req *req, u32 hdrlen,
-                         struct xdr_buf *xdr, enum rpcrdma_chunktype rtype)
+inline int rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt,
+                                    struct rpcrdma_req *req, u32 hdrlen,
+                                    struct xdr_buf *xdr,
+                                    enum rpcrdma_chunktype rtype)
 {
        int ret;
 
        ret = -EAGAIN;
        req->rl_sendctx = rpcrdma_sendctx_get_locked(r_xprt);
        if (!req->rl_sendctx)
-               goto err;
-       req->rl_sendctx->sc_wr.num_sge = 0;
+               goto out_nosc;
        req->rl_sendctx->sc_unmap_count = 0;
        req->rl_sendctx->sc_req = req;
        kref_init(&req->rl_kref);
+       req->rl_wr.wr_cqe = &req->rl_sendctx->sc_cqe;
+       req->rl_wr.sg_list = req->rl_sendctx->sc_sges;
+       req->rl_wr.num_sge = 0;
+       req->rl_wr.opcode = IB_WR_SEND;
 
        ret = -EIO;
        if (!rpcrdma_prepare_hdr_sge(r_xprt, req, hdrlen))
-               goto err;
-       if (rtype != rpcrdma_areadch)
-               if (!rpcrdma_prepare_msg_sges(r_xprt, req, xdr, rtype))
-                       goto err;
+               goto out_unmap;
+
+       switch (rtype) {
+       case rpcrdma_noch_pullup:
+               if (!rpcrdma_prepare_noch_pullup(r_xprt, req, xdr))
+                       goto out_unmap;
+               break;
+       case rpcrdma_noch_mapped:
+               if (!rpcrdma_prepare_noch_mapped(r_xprt, req, xdr))
+                       goto out_unmap;
+               break;
+       case rpcrdma_readch:
+               if (!rpcrdma_prepare_readch(r_xprt, req, xdr))
+                       goto out_unmap;
+               break;
+       case rpcrdma_areadch:
+               break;
+       default:
+               goto out_unmap;
+       }
+
        return 0;
 
-err:
+out_unmap:
+       rpcrdma_sendctx_unmap(req->rl_sendctx);
+out_nosc:
        trace_xprtrdma_prepsend_failed(&req->rl_slot, ret);
        return ret;
 }
@@ -796,6 +893,7 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
        struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
        struct xdr_stream *xdr = &req->rl_stream;
        enum rpcrdma_chunktype rtype, wtype;
+       struct xdr_buf *buf = &rqst->rq_snd_buf;
        bool ddp_allowed;
        __be32 *p;
        int ret;
@@ -853,8 +951,9 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
         */
        if (rpcrdma_args_inline(r_xprt, rqst)) {
                *p++ = rdma_msg;
-               rtype = rpcrdma_noch;
-       } else if (ddp_allowed && rqst->rq_snd_buf.flags & XDRBUF_WRITE) {
+               rtype = buf->len < rdmab_length(req->rl_sendbuf) ?
+                       rpcrdma_noch_pullup : rpcrdma_noch_mapped;
+       } else if (ddp_allowed && buf->flags & XDRBUF_WRITE) {
                *p++ = rdma_msg;
                rtype = rpcrdma_readch;
        } else {
@@ -863,12 +962,6 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
                rtype = rpcrdma_areadch;
        }
 
-       /* If this is a retransmit, discard previously registered
-        * chunks. Very likely the connection has been replaced,
-        * so these registrations are invalid and unusable.
-        */
-       frwr_recycle(req);
-
        /* This implementation supports the following combinations
         * of chunk lists in one RPC-over-RDMA Call message:
         *
@@ -902,7 +995,7 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
                goto out_err;
 
        ret = rpcrdma_prepare_send_sges(r_xprt, req, req->rl_hdrbuf.len,
-                                       &rqst->rq_snd_buf, rtype);
+                                       buf, rtype);
        if (ret)
                goto out_err;
 
@@ -916,6 +1009,40 @@ out_err:
        return ret;
 }
 
+static void __rpcrdma_update_cwnd_locked(struct rpc_xprt *xprt,
+                                        struct rpcrdma_buffer *buf,
+                                        u32 grant)
+{
+       buf->rb_credits = grant;
+       xprt->cwnd = grant << RPC_CWNDSHIFT;
+}
+
+static void rpcrdma_update_cwnd(struct rpcrdma_xprt *r_xprt, u32 grant)
+{
+       struct rpc_xprt *xprt = &r_xprt->rx_xprt;
+
+       spin_lock(&xprt->transport_lock);
+       __rpcrdma_update_cwnd_locked(xprt, &r_xprt->rx_buf, grant);
+       spin_unlock(&xprt->transport_lock);
+}
+
+/**
+ * rpcrdma_reset_cwnd - Reset the xprt's congestion window
+ * @r_xprt: controlling transport instance
+ *
+ * Prepare @r_xprt for the next connection by reinitializing
+ * its credit grant to one (see RFC 8166, Section 3.3.3).
+ */
+void rpcrdma_reset_cwnd(struct rpcrdma_xprt *r_xprt)
+{
+       struct rpc_xprt *xprt = &r_xprt->rx_xprt;
+
+       spin_lock(&xprt->transport_lock);
+       xprt->cong = 0;
+       __rpcrdma_update_cwnd_locked(xprt, &r_xprt->rx_buf, 1);
+       spin_unlock(&xprt->transport_lock);
+}
+
 /**
  * rpcrdma_inline_fixup - Scatter inline received data into rqst's iovecs
  * @rqst: controlling RPC request
@@ -955,7 +1082,6 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
        curlen = rqst->rq_rcv_buf.head[0].iov_len;
        if (curlen > copy_len)
                curlen = copy_len;
-       trace_xprtrdma_fixup(rqst, copy_len, curlen);
        srcp += curlen;
        copy_len -= curlen;
 
@@ -975,8 +1101,6 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
                        if (curlen > pagelist_len)
                                curlen = pagelist_len;
 
-                       trace_xprtrdma_fixup_pg(rqst, i, srcp,
-                                               copy_len, curlen);
                        destp = kmap_atomic(ppages[i]);
                        memcpy(destp + page_base, srcp, curlen);
                        flush_dcache_page(ppages[i]);
@@ -1008,6 +1132,8 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
                rqst->rq_private_buf.tail[0].iov_base = srcp;
        }
 
+       if (fixup_copy_count)
+               trace_xprtrdma_fixup(rqst, fixup_copy_count);
        return fixup_copy_count;
 }
 
@@ -1356,12 +1482,9 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
                credits = 1;    /* don't deadlock */
        else if (credits > buf->rb_max_requests)
                credits = buf->rb_max_requests;
-       if (buf->rb_credits != credits) {
-               spin_lock(&xprt->transport_lock);
-               buf->rb_credits = credits;
-               xprt->cwnd = credits << RPC_CWNDSHIFT;
-               spin_unlock(&xprt->transport_lock);
-       }
+       if (buf->rb_credits != credits)
+               rpcrdma_update_cwnd(r_xprt, credits);
+       rpcrdma_post_recvs(r_xprt, false);
 
        req = rpcr_to_rdmar(rqst);
        if (req->rl_reply) {
index d1fcc41..908e78b 100644 (file)
@@ -195,6 +195,7 @@ rpcrdma_bc_send_request(struct svcxprt_rdma *rdma, struct rpc_rqst *rqst)
        pr_info("%s: %*ph\n", __func__, 64, rqst->rq_buffer);
 #endif
 
+       rqst->rq_xtime = ktime_get();
        rc = svc_rdma_bc_sendto(rdma, rqst, ctxt);
        if (rc) {
                svc_rdma_send_ctxt_put(rdma, ctxt);
index 6fdba72..f3f1080 100644 (file)
@@ -233,11 +233,15 @@ void svc_rdma_send_ctxt_put(struct svcxprt_rdma *rdma,
        /* The first SGE contains the transport header, which
         * remains mapped until @ctxt is destroyed.
         */
-       for (i = 1; i < ctxt->sc_send_wr.num_sge; i++)
+       for (i = 1; i < ctxt->sc_send_wr.num_sge; i++) {
                ib_dma_unmap_page(device,
                                  ctxt->sc_sges[i].addr,
                                  ctxt->sc_sges[i].length,
                                  DMA_TO_DEVICE);
+               trace_svcrdma_dma_unmap_page(rdma,
+                                            ctxt->sc_sges[i].addr,
+                                            ctxt->sc_sges[i].length);
+       }
 
        for (i = 0; i < ctxt->sc_page_count; ++i)
                put_page(ctxt->sc_pages[i]);
@@ -490,6 +494,7 @@ static int svc_rdma_dma_map_page(struct svcxprt_rdma *rdma,
        dma_addr_t dma_addr;
 
        dma_addr = ib_dma_map_page(dev, page, offset, len, DMA_TO_DEVICE);
+       trace_svcrdma_dma_map_page(rdma, dma_addr, len);
        if (ib_dma_mapping_error(dev, dma_addr))
                goto out_maperr;
 
@@ -499,7 +504,6 @@ static int svc_rdma_dma_map_page(struct svcxprt_rdma *rdma,
        return 0;
 
 out_maperr:
-       trace_svcrdma_dma_map_page(rdma, page);
        return -EIO;
 }
 
index 160558b..7395eb2 100644 (file)
@@ -243,16 +243,13 @@ xprt_rdma_connect_worker(struct work_struct *work)
        rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);
        xprt_clear_connecting(xprt);
        if (r_xprt->rx_ep.rep_connected > 0) {
-               if (!xprt_test_and_set_connected(xprt)) {
-                       xprt->stat.connect_count++;
-                       xprt->stat.connect_time += (long)jiffies -
-                                                  xprt->stat.connect_start;
-                       xprt_wake_pending_tasks(xprt, -EAGAIN);
-               }
-       } else {
-               if (xprt_test_and_clear_connected(xprt))
-                       xprt_wake_pending_tasks(xprt, rc);
+               xprt->stat.connect_count++;
+               xprt->stat.connect_time += (long)jiffies -
+                                          xprt->stat.connect_start;
+               xprt_set_connected(xprt);
+               rc = -EAGAIN;
        }
+       xprt_wake_pending_tasks(xprt, rc);
 }
 
 /**
@@ -425,12 +422,6 @@ void xprt_rdma_close(struct rpc_xprt *xprt)
                return;
        rpcrdma_ep_disconnect(ep, ia);
 
-       /* Prepare @xprt for the next connection by reinitializing
-        * its credit grant to one (see RFC 8166, Section 3.3.3).
-        */
-       r_xprt->rx_buf.rb_credits = 1;
-       xprt->cwnd = RPC_CWNDSHIFT;
-
 out:
        xprt->reestablish_timeout = 0;
        ++xprt->connect_cookie;
@@ -450,12 +441,6 @@ xprt_rdma_set_port(struct rpc_xprt *xprt, u16 port)
        struct sockaddr *sap = (struct sockaddr *)&xprt->addr;
        char buf[8];
 
-       dprintk("RPC:       %s: setting port for xprt %p (%s:%s) to %u\n",
-               __func__, xprt,
-               xprt->address_strings[RPC_DISPLAY_ADDR],
-               xprt->address_strings[RPC_DISPLAY_PORT],
-               port);
-
        rpc_set_port(sap, port);
 
        kfree(xprt->address_strings[RPC_DISPLAY_PORT]);
@@ -465,6 +450,9 @@ xprt_rdma_set_port(struct rpc_xprt *xprt, u16 port)
        kfree(xprt->address_strings[RPC_DISPLAY_HEX_PORT]);
        snprintf(buf, sizeof(buf), "%4hx", port);
        xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
+
+       trace_xprtrdma_op_setport(container_of(xprt, struct rpcrdma_xprt,
+                                              rx_xprt));
 }
 
 /**
@@ -536,13 +524,12 @@ xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task)
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
        unsigned long delay;
 
-       trace_xprtrdma_op_connect(r_xprt);
-
        delay = 0;
        if (r_xprt->rx_ep.rep_connected != 0) {
                delay = xprt_reconnect_delay(xprt);
                xprt_reconnect_backoff(xprt, RPCRDMA_INIT_REEST_TO);
        }
+       trace_xprtrdma_op_connect(r_xprt, delay);
        queue_delayed_work(xprtiod_workqueue, &r_xprt->rx_connect_worker,
                           delay);
 }
index 3a90753..77c7dd7 100644 (file)
 /*
  * internal functions
  */
-static void rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc);
+static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
+                                      struct rpcrdma_sendctx *sc);
+static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf);
 static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
-static void rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf);
-static void rpcrdma_mr_free(struct rpcrdma_mr *mr);
+static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt);
 static struct rpcrdma_regbuf *
 rpcrdma_regbuf_alloc(size_t size, enum dma_data_direction direction,
                     gfp_t flags);
 static void rpcrdma_regbuf_dma_unmap(struct rpcrdma_regbuf *rb);
 static void rpcrdma_regbuf_free(struct rpcrdma_regbuf *rb);
-static void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
 
 /* Wait for outstanding transport work to finish. ib_drain_qp
  * handles the drains in the wrong order for us, so open code
@@ -125,7 +125,7 @@ rpcrdma_qp_event_handler(struct ib_event *event, void *context)
 
 /**
  * rpcrdma_wc_send - Invoked by RDMA provider for each polled Send WC
- * @cq:        completion queue (ignored)
+ * @cq:        completion queue
  * @wc:        completed WR
  *
  */
@@ -138,7 +138,7 @@ rpcrdma_wc_send(struct ib_cq *cq, struct ib_wc *wc)
 
        /* WARNING: Only wr_cqe and status are reliable at this point */
        trace_xprtrdma_wc_send(sc, wc);
-       rpcrdma_sendctx_put_locked(sc);
+       rpcrdma_sendctx_put_locked((struct rpcrdma_xprt *)cq->cq_context, sc);
 }
 
 /**
@@ -170,7 +170,6 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
                                   rdmab_addr(rep->rr_rdmabuf),
                                   wc->byte_len, DMA_FROM_DEVICE);
 
-       rpcrdma_post_recvs(r_xprt, false);
        rpcrdma_reply_handler(rep);
        return;
 
@@ -178,11 +177,11 @@ out_flushed:
        rpcrdma_recv_buffer_put(rep);
 }
 
-static void
-rpcrdma_update_connect_private(struct rpcrdma_xprt *r_xprt,
-                              struct rdma_conn_param *param)
+static void rpcrdma_update_cm_private(struct rpcrdma_xprt *r_xprt,
+                                     struct rdma_conn_param *param)
 {
        const struct rpcrdma_connect_private *pmsg = param->private_data;
+       struct rpcrdma_ep *ep = &r_xprt->rx_ep;
        unsigned int rsize, wsize;
 
        /* Default settings for RPC-over-RDMA Version One */
@@ -198,13 +197,11 @@ rpcrdma_update_connect_private(struct rpcrdma_xprt *r_xprt,
                wsize = rpcrdma_decode_buffer_size(pmsg->cp_recv_size);
        }
 
-       if (rsize < r_xprt->rx_ep.rep_inline_recv)
-               r_xprt->rx_ep.rep_inline_recv = rsize;
-       if (wsize < r_xprt->rx_ep.rep_inline_send)
-               r_xprt->rx_ep.rep_inline_send = wsize;
-       dprintk("RPC:       %s: max send %u, max recv %u\n", __func__,
-               r_xprt->rx_ep.rep_inline_send,
-               r_xprt->rx_ep.rep_inline_recv);
+       if (rsize < ep->rep_inline_recv)
+               ep->rep_inline_recv = rsize;
+       if (wsize < ep->rep_inline_send)
+               ep->rep_inline_send = wsize;
+
        rpcrdma_set_max_header_sizes(r_xprt);
 }
 
@@ -258,7 +255,8 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
        case RDMA_CM_EVENT_ESTABLISHED:
                ++xprt->connect_cookie;
                ep->rep_connected = 1;
-               rpcrdma_update_connect_private(r_xprt, &event->param.conn);
+               rpcrdma_update_cm_private(r_xprt, &event->param.conn);
+               trace_xprtrdma_inline_thresh(r_xprt);
                wake_up_all(&ep->rep_connect_wait);
                break;
        case RDMA_CM_EVENT_CONNECT_ERROR:
@@ -298,8 +296,6 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
        struct rdma_cm_id *id;
        int rc;
 
-       trace_xprtrdma_conn_start(xprt);
-
        init_completion(&ia->ri_done);
        init_completion(&ia->ri_remove_done);
 
@@ -315,10 +311,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
        if (rc)
                goto out;
        rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);
-       if (rc < 0) {
-               trace_xprtrdma_conn_tout(xprt);
+       if (rc < 0)
                goto out;
-       }
 
        rc = ia->ri_async_rc;
        if (rc)
@@ -329,10 +323,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
        if (rc)
                goto out;
        rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);
-       if (rc < 0) {
-               trace_xprtrdma_conn_tout(xprt);
+       if (rc < 0)
                goto out;
-       }
        rc = ia->ri_async_rc;
        if (rc)
                goto out;
@@ -409,8 +401,6 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
        struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        struct rpcrdma_req *req;
 
-       cancel_work_sync(&buf->rb_refresh_worker);
-
        /* This is similar to rpcrdma_ep_destroy, but:
         * - Don't cancel the connect worker.
         * - Don't call rpcrdma_ep_disconnect, which waits
@@ -437,7 +427,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
                rpcrdma_regbuf_dma_unmap(req->rl_sendbuf);
                rpcrdma_regbuf_dma_unmap(req->rl_recvbuf);
        }
-       rpcrdma_mrs_destroy(buf);
+       rpcrdma_mrs_destroy(r_xprt);
        ib_dealloc_pd(ia->ri_pd);
        ia->ri_pd = NULL;
 
@@ -522,7 +512,7 @@ int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
        init_waitqueue_head(&ep->rep_connect_wait);
        ep->rep_receive_count = 0;
 
-       sendcq = ib_alloc_cq_any(ia->ri_id->device, NULL,
+       sendcq = ib_alloc_cq_any(ia->ri_id->device, r_xprt,
                                 ep->rep_attr.cap.max_send_wr + 1,
                                 IB_POLL_WORKQUEUE);
        if (IS_ERR(sendcq)) {
@@ -630,8 +620,6 @@ static int rpcrdma_ep_recreate_xprt(struct rpcrdma_xprt *r_xprt,
                pr_err("rpcrdma: rdma_create_qp returned %d\n", err);
                goto out3;
        }
-
-       rpcrdma_mrs_create(r_xprt);
        return 0;
 
 out3:
@@ -649,8 +637,6 @@ static int rpcrdma_ep_reconnect(struct rpcrdma_xprt *r_xprt,
        struct rdma_cm_id *id, *old;
        int err, rc;
 
-       trace_xprtrdma_reconnect(r_xprt);
-
        rpcrdma_ep_disconnect(&r_xprt->rx_ep, ia);
 
        rc = -EHOSTUNREACH;
@@ -705,7 +691,6 @@ retry:
        memcpy(&qp_init_attr, &ep->rep_attr, sizeof(qp_init_attr));
        switch (ep->rep_connected) {
        case 0:
-               dprintk("RPC:       %s: connecting...\n", __func__);
                rc = rdma_create_qp(ia->ri_id, ia->ri_pd, &qp_init_attr);
                if (rc) {
                        rc = -ENETUNREACH;
@@ -726,6 +711,7 @@ retry:
        ep->rep_connected = 0;
        xprt_clear_connected(xprt);
 
+       rpcrdma_reset_cwnd(r_xprt);
        rpcrdma_post_recvs(r_xprt, true);
 
        rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
@@ -742,13 +728,14 @@ retry:
                goto out;
        }
 
-       dprintk("RPC:       %s: connected\n", __func__);
+       rpcrdma_mrs_create(r_xprt);
 
 out:
        if (rc)
                ep->rep_connected = rc;
 
 out_noupdate:
+       trace_xprtrdma_connect(r_xprt, rc);
        return rc;
 }
 
@@ -757,11 +744,8 @@ out_noupdate:
  * @ep: endpoint to disconnect
  * @ia: associated interface adapter
  *
- * This is separate from destroy to facilitate the ability
- * to reconnect without recreating the endpoint.
- *
- * This call is not reentrant, and must not be made in parallel
- * on the same endpoint.
+ * Caller serializes. Either the transport send lock is held,
+ * or we're being called to destroy the transport.
  */
 void
 rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
@@ -780,6 +764,8 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
        trace_xprtrdma_disconnect(r_xprt, rc);
 
        rpcrdma_xprt_drain(r_xprt);
+       rpcrdma_reqs_reset(r_xprt);
+       rpcrdma_mrs_destroy(r_xprt);
 }
 
 /* Fixed-size circular FIFO queue. This implementation is wait-free and
@@ -817,9 +803,6 @@ static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ia *ia)
        if (!sc)
                return NULL;
 
-       sc->sc_wr.wr_cqe = &sc->sc_cqe;
-       sc->sc_wr.sg_list = sc->sc_sges;
-       sc->sc_wr.opcode = IB_WR_SEND;
        sc->sc_cqe.done = rpcrdma_wc_send;
        return sc;
 }
@@ -847,7 +830,6 @@ static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt)
                if (!sc)
                        return -ENOMEM;
 
-               sc->sc_xprt = r_xprt;
                buf->rb_sc_ctxs[i] = sc;
        }
 
@@ -910,6 +892,7 @@ out_emptyq:
 
 /**
  * rpcrdma_sendctx_put_locked - Release a send context
+ * @r_xprt: controlling transport instance
  * @sc: send context to release
  *
  * Usage: Called from Send completion to return a sendctxt
@@ -917,10 +900,10 @@ out_emptyq:
  *
  * The caller serializes calls to this function (per transport).
  */
-static void
-rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc)
+static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
+                                      struct rpcrdma_sendctx *sc)
 {
-       struct rpcrdma_buffer *buf = &sc->sc_xprt->rx_buf;
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        unsigned long next_tail;
 
        /* Unmap SGEs of previously completed but unsignaled
@@ -938,7 +921,7 @@ rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc)
        /* Paired with READ_ONCE */
        smp_store_release(&buf->rb_sc_tail, next_tail);
 
-       xprt_write_space(&sc->sc_xprt->rx_xprt);
+       xprt_write_space(&r_xprt->rx_xprt);
 }
 
 static void
@@ -965,7 +948,7 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
                mr->mr_xprt = r_xprt;
 
                spin_lock(&buf->rb_lock);
-               list_add(&mr->mr_list, &buf->rb_mrs);
+               rpcrdma_mr_push(mr, &buf->rb_mrs);
                list_add(&mr->mr_all, &buf->rb_all_mrs);
                spin_unlock(&buf->rb_lock);
        }
@@ -987,6 +970,28 @@ rpcrdma_mr_refresh_worker(struct work_struct *work)
 }
 
 /**
+ * rpcrdma_mrs_refresh - Wake the MR refresh worker
+ * @r_xprt: controlling transport instance
+ *
+ */
+void rpcrdma_mrs_refresh(struct rpcrdma_xprt *r_xprt)
+{
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+       struct rpcrdma_ep *ep = &r_xprt->rx_ep;
+
+       /* If there is no underlying device, it's no use to
+        * wake the refresh worker.
+        */
+       if (ep->rep_connected != -ENODEV) {
+               /* The work is scheduled on a WQ_MEM_RECLAIM
+                * workqueue in order to prevent MR allocation
+                * from recursing into NFS during direct reclaim.
+                */
+               queue_work(xprtiod_workqueue, &buf->rb_refresh_worker);
+       }
+}
+
+/**
  * rpcrdma_req_create - Allocate an rpcrdma_req object
  * @r_xprt: controlling r_xprt
  * @size: initial size, in bytes, of send and receive buffers
@@ -1042,6 +1047,26 @@ out1:
        return NULL;
 }
 
+/**
+ * rpcrdma_reqs_reset - Reset all reqs owned by a transport
+ * @r_xprt: controlling transport instance
+ *
+ * ASSUMPTION: the rb_allreqs list is stable for the duration,
+ * and thus can be walked without holding rb_lock. Eg. the
+ * caller is holding the transport send lock to exclude
+ * device removal or disconnection.
+ */
+static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt)
+{
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+       struct rpcrdma_req *req;
+
+       list_for_each_entry(req, &buf->rb_allreqs, rl_all) {
+               /* Credits are valid only for one connection */
+               req->rl_slot.rq_cong = 0;
+       }
+}
+
 static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
                                              bool temp)
 {
@@ -1125,8 +1150,6 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
        INIT_LIST_HEAD(&buf->rb_all_mrs);
        INIT_WORK(&buf->rb_refresh_worker, rpcrdma_mr_refresh_worker);
 
-       rpcrdma_mrs_create(r_xprt);
-
        INIT_LIST_HEAD(&buf->rb_send_bufs);
        INIT_LIST_HEAD(&buf->rb_allreqs);
 
@@ -1134,14 +1157,13 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
        for (i = 0; i < buf->rb_max_requests; i++) {
                struct rpcrdma_req *req;
 
-               req = rpcrdma_req_create(r_xprt, RPCRDMA_V1_DEF_INLINE_SIZE,
+               req = rpcrdma_req_create(r_xprt, RPCRDMA_V1_DEF_INLINE_SIZE * 2,
                                         GFP_KERNEL);
                if (!req)
                        goto out;
                list_add(&req->rl_list, &buf->rb_send_bufs);
        }
 
-       buf->rb_credits = 1;
        init_llist_head(&buf->rb_free_reps);
 
        rc = rpcrdma_sendctxs_create(r_xprt);
@@ -1158,15 +1180,24 @@ out:
  * rpcrdma_req_destroy - Destroy an rpcrdma_req object
  * @req: unused object to be destroyed
  *
- * This function assumes that the caller prevents concurrent device
- * unload and transport tear-down.
+ * Relies on caller holding the transport send lock to protect
+ * removing req->rl_all from buf->rb_all_reqs safely.
  */
 void rpcrdma_req_destroy(struct rpcrdma_req *req)
 {
+       struct rpcrdma_mr *mr;
+
        list_del(&req->rl_all);
 
-       while (!list_empty(&req->rl_free_mrs))
-               rpcrdma_mr_free(rpcrdma_mr_pop(&req->rl_free_mrs));
+       while ((mr = rpcrdma_mr_pop(&req->rl_free_mrs))) {
+               struct rpcrdma_buffer *buf = &mr->mr_xprt->rx_buf;
+
+               spin_lock(&buf->rb_lock);
+               list_del(&mr->mr_all);
+               spin_unlock(&buf->rb_lock);
+
+               frwr_release_mr(mr);
+       }
 
        rpcrdma_regbuf_free(req->rl_recvbuf);
        rpcrdma_regbuf_free(req->rl_sendbuf);
@@ -1174,28 +1205,33 @@ void rpcrdma_req_destroy(struct rpcrdma_req *req)
        kfree(req);
 }
 
-static void
-rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
+/**
+ * rpcrdma_mrs_destroy - Release all of a transport's MRs
+ * @r_xprt: controlling transport instance
+ *
+ * Relies on caller holding the transport send lock to protect
+ * removing mr->mr_list from req->rl_free_mrs safely.
+ */
+static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt)
 {
-       struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt,
-                                                  rx_buf);
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        struct rpcrdma_mr *mr;
-       unsigned int count;
 
-       count = 0;
+       cancel_work_sync(&buf->rb_refresh_worker);
+
        spin_lock(&buf->rb_lock);
        while ((mr = list_first_entry_or_null(&buf->rb_all_mrs,
                                              struct rpcrdma_mr,
                                              mr_all)) != NULL) {
+               list_del(&mr->mr_list);
                list_del(&mr->mr_all);
                spin_unlock(&buf->rb_lock);
 
                frwr_release_mr(mr);
-               count++;
+
                spin_lock(&buf->rb_lock);
        }
        spin_unlock(&buf->rb_lock);
-       r_xprt->rx_stats.mrs_allocated = 0;
 }
 
 /**
@@ -1209,8 +1245,6 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
 void
 rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
 {
-       cancel_work_sync(&buf->rb_refresh_worker);
-
        rpcrdma_sendctxs_destroy(buf);
        rpcrdma_reps_destroy(buf);
 
@@ -1222,8 +1256,6 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
                list_del(&req->rl_list);
                rpcrdma_req_destroy(req);
        }
-
-       rpcrdma_mrs_destroy(buf);
 }
 
 /**
@@ -1264,17 +1296,6 @@ void rpcrdma_mr_put(struct rpcrdma_mr *mr)
        rpcrdma_mr_push(mr, &mr->mr_req->rl_free_mrs);
 }
 
-static void rpcrdma_mr_free(struct rpcrdma_mr *mr)
-{
-       struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
-       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
-
-       mr->mr_req = NULL;
-       spin_lock(&buf->rb_lock);
-       rpcrdma_mr_push(mr, &buf->rb_mrs);
-       spin_unlock(&buf->rb_lock);
-}
-
 /**
  * rpcrdma_buffer_get - Get a request buffer
  * @buffers: Buffer pool from which to obtain a buffer
@@ -1437,7 +1458,7 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia,
                struct rpcrdma_ep *ep,
                struct rpcrdma_req *req)
 {
-       struct ib_send_wr *send_wr = &req->rl_sendctx->sc_wr;
+       struct ib_send_wr *send_wr = &req->rl_wr;
        int rc;
 
        if (!ep->rep_send_count || kref_read(&req->rl_kref) > 1) {
@@ -1455,8 +1476,13 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia,
        return 0;
 }
 
-static void
-rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
+/**
+ * rpcrdma_post_recvs - Refill the Receive Queue
+ * @r_xprt: controlling transport instance
+ * @temp: mark Receive buffers to be deleted after use
+ *
+ */
+void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
 {
        struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        struct rpcrdma_ep *ep = &r_xprt->rx_ep;
index 65e6b0e..5d15140 100644 (file)
@@ -218,12 +218,8 @@ enum {
 /* struct rpcrdma_sendctx - DMA mapped SGEs to unmap after Send completes
  */
 struct rpcrdma_req;
-struct rpcrdma_xprt;
 struct rpcrdma_sendctx {
-       struct ib_send_wr       sc_wr;
        struct ib_cqe           sc_cqe;
-       struct ib_device        *sc_device;
-       struct rpcrdma_xprt     *sc_xprt;
        struct rpcrdma_req      *sc_req;
        unsigned int            sc_unmap_count;
        struct ib_sge           sc_sges[];
@@ -257,7 +253,6 @@ struct rpcrdma_mr {
        u32                     mr_handle;
        u32                     mr_length;
        u64                     mr_offset;
-       struct work_struct      mr_recycle;
        struct list_head        mr_all;
 };
 
@@ -318,6 +313,7 @@ struct rpcrdma_req {
        struct rpcrdma_rep      *rl_reply;
        struct xdr_stream       rl_stream;
        struct xdr_buf          rl_hdrbuf;
+       struct ib_send_wr       rl_wr;
        struct rpcrdma_sendctx  *rl_sendctx;
        struct rpcrdma_regbuf   *rl_rdmabuf;    /* xprt header */
        struct rpcrdma_regbuf   *rl_sendbuf;    /* rq_snd_buf */
@@ -474,6 +470,7 @@ void rpcrdma_ep_disconnect(struct rpcrdma_ep *, struct rpcrdma_ia *);
 
 int rpcrdma_ep_post(struct rpcrdma_ia *, struct rpcrdma_ep *,
                                struct rpcrdma_req *);
+void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
 
 /*
  * Buffer calls - xprtrdma/verbs.c
@@ -487,12 +484,7 @@ struct rpcrdma_sendctx *rpcrdma_sendctx_get_locked(struct rpcrdma_xprt *r_xprt);
 
 struct rpcrdma_mr *rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt);
 void rpcrdma_mr_put(struct rpcrdma_mr *mr);
-
-static inline void
-rpcrdma_mr_recycle(struct rpcrdma_mr *mr)
-{
-       schedule_work(&mr->mr_recycle);
-}
+void rpcrdma_mrs_refresh(struct rpcrdma_xprt *r_xprt);
 
 struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);
 void rpcrdma_buffer_put(struct rpcrdma_buffer *buffers,
@@ -542,7 +534,6 @@ rpcrdma_data_dir(bool writing)
 /* Memory registration calls xprtrdma/frwr_ops.c
  */
 bool frwr_is_supported(struct ib_device *device);
-void frwr_recycle(struct rpcrdma_req *req);
 void frwr_reset(struct rpcrdma_req *req);
 int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep);
 int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr);
@@ -563,6 +554,8 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);
 
 enum rpcrdma_chunktype {
        rpcrdma_noch = 0,
+       rpcrdma_noch_pullup,
+       rpcrdma_noch_mapped,
        rpcrdma_readch,
        rpcrdma_areadch,
        rpcrdma_writech,
@@ -576,6 +569,7 @@ int rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt,
 void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc);
 int rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst);
 void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *);
+void rpcrdma_reset_cwnd(struct rpcrdma_xprt *r_xprt);
 void rpcrdma_complete_rqst(struct rpcrdma_rep *rep);
 void rpcrdma_reply_handler(struct rpcrdma_rep *rep);
 
index 70e52f5..d86c664 100644 (file)
@@ -1752,7 +1752,7 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
 
 static void xs_set_srcport(struct sock_xprt *transport, struct socket *sock)
 {
-       if (transport->srcport == 0)
+       if (transport->srcport == 0 && transport->xprt.reuseport)
                transport->srcport = xs_sock_getport(sock);
 }
 
@@ -2659,6 +2659,8 @@ static int bc_sendto(struct rpc_rqst *req)
                .iov_len        = sizeof(marker),
        };
 
+       req->rq_xtime = ktime_get();
+
        len = kernel_sendmsg(transport->sock, &msg, &iov, 1, iov.iov_len);
        if (len != iov.iov_len)
                return -EAGAIN;
@@ -2684,7 +2686,6 @@ static int bc_send_request(struct rpc_rqst *req)
        struct svc_xprt *xprt;
        int len;
 
-       dprintk("sending request with xid: %08x\n", ntohl(req->rq_xid));
        /*
         * Get the server socket associated with this callback xprt
         */
index 7532a00..4f6dc74 100644 (file)
@@ -148,14 +148,6 @@ static int __init tipc_init(void)
        sysctl_tipc_rmem[1] = RCVBUF_DEF;
        sysctl_tipc_rmem[2] = RCVBUF_MAX;
 
-       err = tipc_netlink_start();
-       if (err)
-               goto out_netlink;
-
-       err = tipc_netlink_compat_start();
-       if (err)
-               goto out_netlink_compat;
-
        err = tipc_register_sysctl();
        if (err)
                goto out_sysctl;
@@ -180,8 +172,21 @@ static int __init tipc_init(void)
        if (err)
                goto out_bearer;
 
+       err = tipc_netlink_start();
+       if (err)
+               goto out_netlink;
+
+       err = tipc_netlink_compat_start();
+       if (err)
+               goto out_netlink_compat;
+
        pr_info("Started in single node mode\n");
        return 0;
+
+out_netlink_compat:
+       tipc_netlink_stop();
+out_netlink:
+       tipc_bearer_cleanup();
 out_bearer:
        unregister_pernet_subsys(&tipc_pernet_pre_exit_ops);
 out_register_pernet_subsys:
@@ -193,23 +198,19 @@ out_socket:
 out_pernet:
        tipc_unregister_sysctl();
 out_sysctl:
-       tipc_netlink_compat_stop();
-out_netlink_compat:
-       tipc_netlink_stop();
-out_netlink:
        pr_err("Unable to start in single node mode\n");
        return err;
 }
 
 static void __exit tipc_exit(void)
 {
+       tipc_netlink_compat_stop();
+       tipc_netlink_stop();
        tipc_bearer_cleanup();
        unregister_pernet_subsys(&tipc_pernet_pre_exit_ops);
        unregister_pernet_device(&tipc_topsrv_net_ops);
        tipc_socket_stop();
        unregister_pernet_device(&tipc_net_ops);
-       tipc_netlink_stop();
-       tipc_netlink_compat_stop();
        tipc_unregister_sysctl();
 
        pr_info("Deactivated\n");
index 86aaa4d..ed11373 100644 (file)
@@ -195,10 +195,13 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
                                .saddr = src->ipv6,
                                .flowi6_proto = IPPROTO_UDP
                        };
-                       err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk,
-                                                        &ndst, &fl6);
-                       if (err)
+                       ndst = ipv6_stub->ipv6_dst_lookup_flow(net,
+                                                              ub->ubsock->sk,
+                                                              &fl6, NULL);
+                       if (IS_ERR(ndst)) {
+                               err = PTR_ERR(ndst);
                                goto tx_error;
+                       }
                        dst_cache_set_ip6(cache, ndst, &fl6.saddr);
                }
                ttl = ip6_dst_hoplimit(ndst);
index 0683788..cd91ad8 100644 (file)
@@ -429,7 +429,7 @@ static int tls_push_data(struct sock *sk,
 
        if (flags &
            ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        if (unlikely(sk->sk_err))
                return -sk->sk_err;
@@ -571,7 +571,7 @@ int tls_device_sendpage(struct sock *sk, struct page *page,
        lock_sock(sk);
 
        if (flags & MSG_OOB) {
-               rc = -ENOTSUPP;
+               rc = -EOPNOTSUPP;
                goto out;
        }
 
@@ -1023,7 +1023,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
        }
 
        if (!(netdev->features & NETIF_F_HW_TLS_TX)) {
-               rc = -ENOTSUPP;
+               rc = -EOPNOTSUPP;
                goto release_netdev;
        }
 
@@ -1098,7 +1098,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx)
        }
 
        if (!(netdev->features & NETIF_F_HW_TLS_RX)) {
-               rc = -ENOTSUPP;
+               rc = -EOPNOTSUPP;
                goto release_netdev;
        }
 
index b3da6c5..dac24c7 100644 (file)
@@ -487,7 +487,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
        /* check version */
        if (crypto_info->version != TLS_1_2_VERSION &&
            crypto_info->version != TLS_1_3_VERSION) {
-               rc = -ENOTSUPP;
+               rc = -EINVAL;
                goto err_crypto_info;
        }
 
@@ -714,7 +714,7 @@ static int tls_init(struct sock *sk)
         * share the ulp context.
         */
        if (sk->sk_state != TCP_ESTABLISHED)
-               return -ENOTSUPP;
+               return -ENOTCONN;
 
        /* allocate tls context */
        write_lock_bh(&sk->sk_callback_lock);
index 2b2d0ba..c6803a8 100644 (file)
@@ -905,7 +905,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
        int ret = 0;
 
        if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        mutex_lock(&tls_ctx->tx_lock);
        lock_sock(sk);
@@ -1220,7 +1220,7 @@ int tls_sw_sendpage_locked(struct sock *sk, struct page *page,
        if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
                      MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY |
                      MSG_NO_SHARED_FRAGS))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        return tls_sw_do_sendpage(sk, page, offset, size, flags);
 }
@@ -1233,7 +1233,7 @@ int tls_sw_sendpage(struct sock *sk, struct page *page,
 
        if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
                      MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        mutex_lock(&tls_ctx->tx_lock);
        lock_sock(sk);
@@ -1932,7 +1932,7 @@ ssize_t tls_sw_splice_read(struct socket *sock,  loff_t *ppos,
 
                /* splice does not support reading control messages */
                if (ctx->control != TLS_RECORD_TYPE_DATA) {
-                       err = -ENOTSUPP;
+                       err = -EINVAL;
                        goto splice_read_end;
                }
 
index 7cfdce1..774babb 100644 (file)
@@ -2865,7 +2865,7 @@ static int __init af_unix_init(void)
 {
        int rc = -1;
 
-       BUILD_BUG_ON(sizeof(struct unix_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
+       BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof_field(struct sk_buff, cb));
 
        rc = proto_register(&unix_proto, 1);
        if (rc != 0) {
index 51e0d81..8fc3ad0 100644 (file)
@@ -489,9 +489,9 @@ int main(int argc, char **argv)
        if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
                return EXIT_FAIL;
 
-       map = bpf_map__next(NULL, obj);
-       stats_global_map = bpf_map__next(map, obj);
-       rx_queue_index_map = bpf_map__next(stats_global_map, obj);
+       map =  bpf_object__find_map_by_name(obj, "config_map");
+       stats_global_map = bpf_object__find_map_by_name(obj, "stats_global_map");
+       rx_queue_index_map = bpf_object__find_map_by_name(obj, "rx_queue_index_map");
        if (!map || !stats_global_map || !rx_queue_index_map) {
                printf("finding a map in obj file failed\n");
                return EXIT_FAIL;
index 592911a..a63380c 100755 (executable)
@@ -874,14 +874,18 @@ sub seed_camelcase_file {
        }
 }
 
+our %maintained_status = ();
+
 sub is_maintained_obsolete {
        my ($filename) = @_;
 
        return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
 
-       my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
+       if (!exists($maintained_status{$filename})) {
+               $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
+       }
 
-       return $status =~ /obsolete/i;
+       return $maintained_status{$filename} =~ /obsolete/i;
 }
 
 sub is_SPDX_License_valid {
@@ -4121,15 +4125,6 @@ sub process {
                             "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
                }
 
-               if ($line =~ /\bpr_warning\s*\(/) {
-                       if (WARN("PREFER_PR_LEVEL",
-                                "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
-                           $fix) {
-                               $fixed[$fixlinenr] =~
-                                   s/\bpr_warning\b/pr_warn/;
-                       }
-               }
-
                if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
                        my $orig = $1;
                        my $level = lc($orig);
@@ -5038,8 +5033,9 @@ sub process {
                            $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
 #Ignore Page<foo> variants
                            $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
-#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
-                           $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
+#Ignore SI style variants like nS, mV and dB
+#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
+                           $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
 #Ignore some three character SI units explicitly, like MiB and KHz
                            $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
                                while ($var =~ m{($Ident)}g) {
index 5ef5921..34085d1 100755 (executable)
@@ -26,6 +26,7 @@ my $email = 1;
 my $email_usename = 1;
 my $email_maintainer = 1;
 my $email_reviewer = 1;
+my $email_fixes = 1;
 my $email_list = 1;
 my $email_moderated_list = 1;
 my $email_subscriber_list = 0;
@@ -249,6 +250,7 @@ if (!GetOptions(
                'r!' => \$email_reviewer,
                'n!' => \$email_usename,
                'l!' => \$email_list,
+               'fixes!' => \$email_fixes,
                'moderated!' => \$email_moderated_list,
                's!' => \$email_subscriber_list,
                'multiline!' => \$output_multiline,
@@ -503,6 +505,7 @@ sub read_mailmap {
 ## use the filenames on the command line or find the filenames in the patchfiles
 
 my @files = ();
+my @fixes = ();                        # If a patch description includes Fixes: lines
 my @range = ();
 my @keyword_tvi = ();
 my @file_emails = ();
@@ -568,6 +571,8 @@ foreach my $file (@ARGV) {
                my $filename2 = $2;
                push(@files, $filename1);
                push(@files, $filename2);
+           } elsif (m/^Fixes:\s+([0-9a-fA-F]{6,40})/) {
+               push(@fixes, $1) if ($email_fixes);
            } elsif (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) {
                my $filename = $1;
                $filename =~ s@^[^/]*/@@;
@@ -598,6 +603,7 @@ foreach my $file (@ARGV) {
 }
 
 @file_emails = uniq(@file_emails);
+@fixes = uniq(@fixes);
 
 my %email_hash_name;
 my %email_hash_address;
@@ -612,7 +618,6 @@ my %deduplicate_name_hash = ();
 my %deduplicate_address_hash = ();
 
 my @maintainers = get_maintainers();
-
 if (@maintainers) {
     @maintainers = merge_email(@maintainers);
     output(@maintainers);
@@ -927,6 +932,10 @@ sub get_maintainers {
        }
     }
 
+    foreach my $fix (@fixes) {
+       vcs_add_commit_signers($fix, "blamed_fixes");
+    }
+
     foreach my $email (@email_to, @list_to) {
        $email->[0] = deduplicate_email($email->[0]);
     }
@@ -1031,6 +1040,7 @@ MAINTAINER field selection options:
     --roles => show roles (status:subsystem, git-signer, list, etc...)
     --rolestats => show roles and statistics (commits/total_commits, %)
     --file-emails => add email addresses found in -f file (default: 0 (off))
+    --fixes => for patches, add signatures of commits with 'Fixes: <commit>' (default: 1 (on))
   --scm => print SCM tree(s) if any
   --status => print status if any
   --subsystem => print subsystem name if any
@@ -1730,6 +1740,32 @@ sub vcs_is_hg {
     return $vcs_used == 2;
 }
 
+sub vcs_add_commit_signers {
+    return if (!vcs_exists());
+
+    my ($commit, $desc) = @_;
+    my $commit_count = 0;
+    my $commit_authors_ref;
+    my $commit_signers_ref;
+    my $stats_ref;
+    my @commit_authors = ();
+    my @commit_signers = ();
+    my $cmd;
+
+    $cmd = $VCS_cmds{"find_commit_signers_cmd"};
+    $cmd =~ s/(\$\w+)/$1/eeg;  #substitute variables in $cmd
+
+    ($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, "");
+    @commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref;
+    @commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref;
+
+    foreach my $signer (@commit_signers) {
+       $signer = deduplicate_email($signer);
+    }
+
+    vcs_assign($desc, 1, @commit_signers);
+}
+
 sub interactive_get_maintainers {
     my ($list_ref) = @_;
     my @list = @$list_ref;
index 0649537..4363799 100755 (executable)
@@ -127,7 +127,9 @@ gen_btf()
                cut -d, -f1 | cut -d' ' -f2)
        bin_format=$(LANG=C ${OBJDUMP} -f ${1} | grep 'file format' | \
                awk '{print $4}')
-       ${OBJCOPY} --dump-section .BTF=.btf.vmlinux.bin ${1} 2>/dev/null
+       ${OBJCOPY} --change-section-address .BTF=0 \
+               --set-section-flags .BTF=alloc -O binary \
+               --only-section=.BTF ${1} .btf.vmlinux.bin
        ${OBJCOPY} -I binary -O ${bin_format} -B ${bin_arch} \
                --rename-section .data=.BTF .btf.vmlinux.bin ${2}
 }
@@ -253,6 +255,10 @@ btf_vmlinux_bin_o=""
 if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
        if gen_btf .tmp_vmlinux.btf .btf.vmlinux.bin.o ; then
                btf_vmlinux_bin_o=.btf.vmlinux.bin.o
+       else
+               echo >&2 "Failed to generate BTF for vmlinux"
+               echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF"
+               exit 1
        fi
 fi
 
index f19a895..ef8dfd4 100644 (file)
@@ -45,7 +45,7 @@
 #define DONT_HASH      0x0200
 
 #define INVALID_PCR(a) (((a) < 0) || \
-       (a) >= (FIELD_SIZEOF(struct integrity_iint_cache, measured_pcrs) * 8))
+       (a) >= (sizeof_field(struct integrity_iint_cache, measured_pcrs) * 8))
 
 int ima_policy_flag;
 static int temp_ima_appraise;
@@ -274,7 +274,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
         * lsm rules can change
         */
        memcpy(nentry, entry, sizeof(*nentry));
-       memset(nentry->lsm, 0, FIELD_SIZEOF(struct ima_rule_entry, lsm));
+       memset(nentry->lsm, 0, sizeof_field(struct ima_rule_entry, lsm));
 
        for (i = 0; i < MAX_LSM_RULES; i++) {
                if (!entry->lsm[i].rule)
index 2045697..797d838 100644 (file)
@@ -107,6 +107,8 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
                }
        }
 #endif
+       if (frames > dst_channels[0].frames)
+               frames = dst_channels[0].frames;
        convert(plugin, src_channels, dst_channels, frames);
        return frames;
 }
index 7915564..3788906 100644 (file)
@@ -269,6 +269,8 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
                }
        }
 #endif
+       if (frames > dst_channels[0].frames)
+               frames = dst_channels[0].frames;
        data = (struct mulaw_priv *)plugin->extra_data;
        data->func(plugin, src_channels, dst_channels, frames);
        return frames;
index c8171f5..72dea04 100644 (file)
@@ -57,6 +57,8 @@ static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
                return -ENXIO;
        if (frames == 0)
                return 0;
+       if (frames > dst_channels[0].frames)
+               frames = dst_channels[0].frames;
 
        nsrcs = plugin->src_format.channels;
        ndsts = plugin->dst_format.channels;
index 0ebfbe7..6bb4642 100644 (file)
@@ -727,10 +727,6 @@ static void loopback_snd_timer_period_elapsed(struct loopback_cable *cable,
 
        dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
        dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE];
-       substream_play = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
-                       dpcm_play->substream : NULL;
-       substream_capt = (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) ?
-                       dpcm_capt->substream : NULL;
 
        if (event == SNDRV_TIMER_EVENT_MSTOP) {
                if (!dpcm_play ||
@@ -741,6 +737,10 @@ static void loopback_snd_timer_period_elapsed(struct loopback_cable *cable,
                }
        }
 
+       substream_play = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
+                       dpcm_play->substream : NULL;
+       substream_capt = (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) ?
+                       dpcm_capt->substream : NULL;
        valid_runtime = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
                                dpcm_play->substream->runtime :
                                dpcm_capt->substream->runtime;
index 4e3bd9a..bd91c6e 100644 (file)
@@ -247,7 +247,7 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
                mutex_unlock(&ff->mutex);
        }
 
-       return 0;
+       return err;
 }
 
 static int pcm_hw_free(struct snd_pcm_substream *substream)
index 349b4d0..0059709 100644 (file)
@@ -177,18 +177,14 @@ static int pcm_open(struct snd_pcm_substream *substream)
                        err = snd_pcm_hw_constraint_minmax(substream->runtime,
                                        SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
                                        frames_per_period, frames_per_period);
-                       if (err < 0) {
-                               mutex_unlock(&motu->mutex);
+                       if (err < 0)
                                goto err_locked;
-                       }
 
                        err = snd_pcm_hw_constraint_minmax(substream->runtime,
                                        SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
                                        frames_per_buffer, frames_per_buffer);
-                       if (err < 0) {
-                               mutex_unlock(&motu->mutex);
+                       if (err < 0)
                                goto err_locked;
-                       }
                }
        }
 
index 9124603..67fd3e8 100644 (file)
@@ -285,7 +285,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
                mutex_unlock(&oxfw->mutex);
        }
 
-       return 0;
+       return err;
 }
 
 static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
index d8fe7ff..f9707fb 100644 (file)
@@ -96,12 +96,14 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start)
                              1 << azx_dev->index,
                              1 << azx_dev->index);
        /* set stripe control */
-       if (azx_dev->substream)
-               stripe_ctl = snd_hdac_get_stream_stripe_ctl(bus, azx_dev->substream);
-       else
-               stripe_ctl = 0;
-       snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
-                               stripe_ctl);
+       if (azx_dev->stripe) {
+               if (azx_dev->substream)
+                       stripe_ctl = snd_hdac_get_stream_stripe_ctl(bus, azx_dev->substream);
+               else
+                       stripe_ctl = 0;
+               snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
+                                       stripe_ctl);
+       }
        /* set DMA start and interrupt mask */
        snd_hdac_stream_updateb(azx_dev, SD_CTL,
                                0, SD_CTL_DMA_START | SD_INT_MASK);
@@ -118,7 +120,10 @@ void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
        snd_hdac_stream_updateb(azx_dev, SD_CTL,
                                SD_CTL_DMA_START | SD_INT_MASK, 0);
        snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
-       snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
+       if (azx_dev->stripe) {
+               snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
+               azx_dev->stripe = 0;
+       }
        azx_dev->running = false;
 }
 EXPORT_SYMBOL_GPL(snd_hdac_stream_clear);
index 50d4a87..f02f5b1 100644 (file)
@@ -635,36 +635,30 @@ This function assumes there are no more than 16 in/out busses or pipes
 Meters is an array [3][16][2] of long. */
 static void get_audio_meters(struct echoaudio *chip, long *meters)
 {
-       int i, m, n;
+       unsigned int i, m, n;
 
-       m = 0;
-       n = 0;
-       for (i = 0; i < num_busses_out(chip); i++, m++) {
+       for (i = 0 ; i < 96; i++)
+               meters[i] = 0;
+
+       for (m = 0, n = 0, i = 0; i < num_busses_out(chip); i++, m++) {
                meters[n++] = chip->comm_page->vu_meter[m];
                meters[n++] = chip->comm_page->peak_meter[m];
        }
-       for (; n < 32; n++)
-               meters[n] = 0;
 
 #ifdef ECHOCARD_ECHO3G
        m = E3G_MAX_OUTPUTS;    /* Skip unused meters */
 #endif
 
-       for (i = 0; i < num_busses_in(chip); i++, m++) {
+       for (n = 32, i = 0; i < num_busses_in(chip); i++, m++) {
                meters[n++] = chip->comm_page->vu_meter[m];
                meters[n++] = chip->comm_page->peak_meter[m];
        }
-       for (; n < 64; n++)
-               meters[n] = 0;
-
 #ifdef ECHOCARD_HAS_VMIXER
-       for (i = 0; i < num_pipes_out(chip); i++, m++) {
+       for (n = 64, i = 0; i < num_pipes_out(chip); i++, m++) {
                meters[n++] = chip->comm_page->vu_meter[m];
                meters[n++] = chip->comm_page->peak_meter[m];
        }
 #endif
-       for (; n < 96; n++)
-               meters[n] = 0;
 }
 
 
index e76a0bb..b856b89 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/clocksource.h>
 #include <linux/time.h>
 #include <linux/completion.h>
+#include <linux/acpi.h>
 
 #ifdef CONFIG_X86
 /* for snoop control */
@@ -1401,6 +1402,33 @@ static int azx_dev_free(struct snd_device *device)
 }
 
 #ifdef SUPPORT_VGA_SWITCHEROO
+#ifdef CONFIG_ACPI
+/* ATPX is in the integrated GPU's namespace */
+static bool atpx_present(void)
+{
+       struct pci_dev *pdev = NULL;
+       acpi_handle dhandle, atpx_handle;
+       acpi_status status;
+
+       while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) {
+               dhandle = ACPI_HANDLE(&pdev->dev);
+               if (dhandle) {
+                       status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
+                       if (!ACPI_FAILURE(status)) {
+                               pci_dev_put(pdev);
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
+#else
+static bool atpx_present(void)
+{
+       return false;
+}
+#endif
+
 /*
  * Check of disabled HDMI controller by vga_switcheroo
  */
@@ -1412,6 +1440,22 @@ static struct pci_dev *get_bound_vga(struct pci_dev *pci)
        switch (pci->vendor) {
        case PCI_VENDOR_ID_ATI:
        case PCI_VENDOR_ID_AMD:
+               if (pci->devfn == 1) {
+                       p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
+                                                       pci->bus->number, 0);
+                       if (p) {
+                               /* ATPX is in the integrated GPU's ACPI namespace
+                                * rather than the dGPU's namespace. However,
+                                * the dGPU is the one who is involved in
+                                * vgaswitcheroo.
+                                */
+                               if (((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
+                                   atpx_present())
+                                       return p;
+                               pci_dev_put(p);
+                       }
+               }
+               break;
        case PCI_VENDOR_ID_NVIDIA:
                if (pci->devfn == 1) {
                        p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
@@ -2547,13 +2591,38 @@ static const struct pci_device_id azx_ids[] = {
        { PCI_DEVICE(0x1002, 0xaac8),
          .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
        { PCI_DEVICE(0x1002, 0xaad8),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
-       { PCI_DEVICE(0x1002, 0xaae8),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
        { PCI_DEVICE(0x1002, 0xaae0),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xaae8),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
        { PCI_DEVICE(0x1002, 0xaaf0),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xaaf8),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xab00),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xab08),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xab10),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xab18),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xab20),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
+       { PCI_DEVICE(0x1002, 0xab38),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+         AZX_DCAPS_PM_RUNTIME },
        /* VIA VT8251/VT8237A */
        { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
        /* VIA GFX VT7122/VX900 */
index bffde59..78647ee 100644 (file)
@@ -32,6 +32,7 @@
 #include <sound/hda_codec.h>
 #include "hda_local.h"
 #include "hda_jack.h"
+#include "hda_controller.h"
 
 static bool static_hdmi_pcm;
 module_param(static_hdmi_pcm, bool, 0644);
@@ -1249,6 +1250,10 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
        per_pin->cvt_nid = per_cvt->cvt_nid;
        hinfo->nid = per_cvt->cvt_nid;
 
+       /* flip stripe flag for the assigned stream if supported */
+       if (get_wcaps(codec, per_cvt->cvt_nid) & AC_WCAP_STRIPE)
+               azx_stream(get_azx_dev(substream))->stripe = 1;
+
        snd_hda_set_dev_select(codec, per_pin->pin_nid, per_pin->dev_id);
        snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
                            AC_VERB_SET_CONNECT_SEL,
@@ -1302,6 +1307,7 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
        struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
        hda_nid_t pin_nid = per_pin->pin_nid;
        int dev_id = per_pin->dev_id;
+       int conns;
 
        if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
                codec_warn(codec,
@@ -1312,10 +1318,18 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
 
        snd_hda_set_dev_select(codec, pin_nid, dev_id);
 
+       if (spec->intel_hsw_fixup) {
+               conns = spec->num_cvts;
+               memcpy(per_pin->mux_nids, spec->cvt_nids,
+                      sizeof(hda_nid_t) * conns);
+       } else {
+               conns = snd_hda_get_raw_connections(codec, pin_nid,
+                                                   per_pin->mux_nids,
+                                                   HDA_MAX_CONNECTIONS);
+       }
+
        /* all the device entries on the same pin have the same conn list */
-       per_pin->num_mux_nids =
-               snd_hda_get_raw_connections(codec, pin_nid, per_pin->mux_nids,
-                                           HDA_MAX_CONNECTIONS);
+       per_pin->num_mux_nids = conns;
 
        return 0;
 }
@@ -1326,24 +1340,26 @@ static int hdmi_find_pcm_slot(struct hdmi_spec *spec,
        int i;
 
        /*
-        * generic_hdmi_build_pcms() allocates (num_nids + dev_num - 1)
-        * number of pcms.
+        * generic_hdmi_build_pcms() may allocate extra PCMs on some
+        * platforms (with maximum of 'num_nids + dev_num - 1')
         *
         * The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n
         * if m==0. This guarantees that dynamic pcm assignments are compatible
-        * with the legacy static per_pin-pmc assignment that existed in the
+        * with the legacy static per_pin-pcm assignment that existed in the
         * days before DP-MST.
         *
+        * Intel DP-MST prefers this legacy behavior for compatibility, too.
+        *
         * per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)).
         */
-       if (per_pin->dev_id == 0 &&
-           !test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
-               return per_pin->pin_nid_idx;
-
-       if (per_pin->dev_id != 0 &&
-           !(test_bit(spec->num_nids + (per_pin->dev_id - 1),
-               &spec->pcm_bitmap))) {
-               return spec->num_nids + (per_pin->dev_id - 1);
+
+       if (per_pin->dev_id == 0 || spec->intel_hsw_fixup) {
+               if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
+                       return per_pin->pin_nid_idx;
+       } else {
+               i = spec->num_nids + (per_pin->dev_id - 1);
+               if (i < spec->pcm_used && !(test_bit(i, &spec->pcm_bitmap)))
+                       return i;
        }
 
        /* have a second try; check the area over num_nids */
@@ -1713,9 +1729,6 @@ static void hdmi_repoll_eld(struct work_struct *work)
        mutex_unlock(&spec->pcm_lock);
 }
 
-static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
-                                            hda_nid_t nid);
-
 static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
 {
        struct hdmi_spec *spec = codec->spec;
@@ -1790,8 +1803,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
                per_pin->dev_id = i;
                per_pin->non_pcm = false;
                snd_hda_set_dev_select(codec, pin_nid, i);
-               if (spec->intel_hsw_fixup)
-                       intel_haswell_fixup_connect_list(codec, pin_nid);
                err = hdmi_read_pin_conn(codec, pin_idx);
                if (err < 0)
                        return err;
@@ -2603,24 +2614,6 @@ static void generic_acomp_init(struct hda_codec *codec,
  * Intel codec parsers and helpers
  */
 
-static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
-                                            hda_nid_t nid)
-{
-       struct hdmi_spec *spec = codec->spec;
-       hda_nid_t conns[4];
-       int nconns;
-
-       nconns = snd_hda_get_raw_connections(codec, nid, conns,
-                                            ARRAY_SIZE(conns));
-       if (nconns == spec->num_cvts &&
-           !memcmp(conns, spec->cvt_nids, spec->num_cvts * sizeof(hda_nid_t)))
-               return;
-
-       /* override pins connection list */
-       codec_dbg(codec, "hdmi: haswell: override pin connection 0x%x\n", nid);
-       snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids);
-}
-
 #define INTEL_GET_VENDOR_VERB  0xf81
 #define INTEL_SET_VENDOR_VERB  0x781
 #define INTEL_EN_DP12          0x02    /* enable DP 1.2 features */
@@ -4063,6 +4056,7 @@ static int atihdmi_init(struct hda_codec *codec)
                                            ATI_VERB_SET_MULTICHANNEL_MODE,
                                            ATI_MULTICHANNEL_MODE_SINGLE);
        }
+       codec->auto_runtime_pm = 1;
 
        return 0;
 }
index d2bf70a..dbfafee 100644 (file)
@@ -367,9 +367,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
        case 0x10ec0215:
        case 0x10ec0233:
        case 0x10ec0235:
-       case 0x10ec0236:
        case 0x10ec0255:
-       case 0x10ec0256:
        case 0x10ec0257:
        case 0x10ec0282:
        case 0x10ec0283:
@@ -381,6 +379,11 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
        case 0x10ec0300:
                alc_update_coef_idx(codec, 0x10, 1<<9, 0);
                break;
+       case 0x10ec0236:
+       case 0x10ec0256:
+               alc_write_coef_idx(codec, 0x36, 0x5757);
+               alc_update_coef_idx(codec, 0x10, 1<<9, 0);
+               break;
        case 0x10ec0275:
                alc_update_coef_idx(codec, 0xe, 0, 1<<0);
                break;
@@ -5544,6 +5547,16 @@ static void alc295_fixup_disable_dac3(struct hda_codec *codec,
        }
 }
 
+/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
+static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
+                                         const struct hda_fixup *fix, int action)
+{
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               hda_nid_t conn[1] = { 0x02 };
+               snd_hda_override_conn_list(codec, 0x17, 1, conn);
+       }
+}
+
 /* Hook to update amp GPIO4 for automute */
 static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
                                          struct hda_jack_callback *jack)
@@ -5846,6 +5859,7 @@ enum {
        ALC225_FIXUP_DISABLE_MIC_VREF,
        ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
        ALC295_FIXUP_DISABLE_DAC3,
+       ALC285_FIXUP_SPEAKER2_TO_DAC1,
        ALC280_FIXUP_HP_HEADSET_MIC,
        ALC221_FIXUP_HP_FRONT_MIC,
        ALC292_FIXUP_TPT460,
@@ -6646,6 +6660,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc295_fixup_disable_dac3,
        },
+       [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc285_fixup_speaker2_to_dac1,
+       },
        [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -7221,6 +7239,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
@@ -7405,6 +7424,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
        {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
        {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
+       {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
        {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
        {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
        {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
@@ -7623,11 +7643,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
                {0x1a, 0x90a70130},
                {0x1b, 0x90170110},
                {0x21, 0x03211020}),
-       SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
-               {0x12, 0xb7a60130},
-               {0x13, 0xb8a61140},
-               {0x16, 0x90170110},
-               {0x21, 0x04211020}),
        SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
                {0x12, 0x90a60130},
                {0x14, 0x90170110},
@@ -7821,6 +7836,9 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
        SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
                {0x19, 0x40000000},
                {0x1a, 0x40000000}),
+       SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
+               {0x19, 0x40000000},
+               {0x1a, 0x40000000}),
        {}
 };
 
@@ -8424,6 +8442,8 @@ static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
        case HDA_FIXUP_ACT_PRE_PROBE:
                snd_hda_jack_detect_enable_callback(codec, 0x1b,
                                alc662_aspire_ethos_mute_speakers);
+               /* subwoofer needs an extra GPIO setting to become audible */
+               alc_setup_gpio(codec, 0x02);
                break;
        case HDA_FIXUP_ACT_INIT:
                /* Make sure to start in a correct state, i.e. if
@@ -8506,7 +8526,6 @@ enum {
        ALC662_FIXUP_USI_HEADSET_MODE,
        ALC662_FIXUP_LENOVO_MULTI_CODECS,
        ALC669_FIXUP_ACER_ASPIRE_ETHOS,
-       ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER,
        ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
 };
 
@@ -8838,18 +8857,6 @@ static const struct hda_fixup alc662_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc662_fixup_aspire_ethos_hp,
        },
-       [ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER] = {
-               .type = HDA_FIXUP_VERBS,
-               /* subwoofer needs an extra GPIO setting to become audible */
-               .v.verbs = (const struct hda_verb[]) {
-                       {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
-                       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
-                       {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
-                       { }
-               },
-               .chained = true,
-               .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
-       },
        [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -8859,7 +8866,7 @@ static const struct hda_fixup alc662_fixups[] = {
                        { }
                },
                .chained = true,
-               .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER
+               .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
        },
 };
 
index f8b5b96..4eaa2b5 100644 (file)
@@ -292,7 +292,7 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_info *uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
-       uinfo->count = FIELD_SIZEOF(struct hdmi_codec_priv, eld);
+       uinfo->count = sizeof_field(struct hdmi_codec_priv, eld);
 
        return 0;
 }
index 35bf013..e97c2eb 100644 (file)
@@ -1,7 +1,6 @@
 libbpf_version.h
 libbpf.pc
 FEATURE-DUMP.libbpf
-test_libbpf
 libbpf.so.*
 TAGS
 tags
index 99425d0..defae23 100644 (file)
@@ -147,12 +147,12 @@ TAGS_PROG := $(if $(shell which etags 2>/dev/null),etags,ctags)
 
 GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
                           cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \
-                          awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \
+                          awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}' | \
                           sort -u | wc -l)
 VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \
                              grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
 
-CMD_TARGETS = $(LIB_TARGET) $(PC_FILE) $(OUTPUT)test_libbpf
+CMD_TARGETS = $(LIB_TARGET) $(PC_FILE)
 
 all: fixdep
        $(Q)$(MAKE) all_cmd
@@ -180,9 +180,9 @@ $(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h
 $(BPF_IN_STATIC): force elfdep bpfdep bpf_helper_defs.h
        $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR)
 
-bpf_helper_defs.h: $(srctree)/include/uapi/linux/bpf.h
+bpf_helper_defs.h: $(srctree)/tools/include/uapi/linux/bpf.h
        $(Q)$(srctree)/scripts/bpf_helpers_doc.py --header              \
-               --file $(srctree)/include/uapi/linux/bpf.h > bpf_helper_defs.h
+               --file $(srctree)/tools/include/uapi/linux/bpf.h > bpf_helper_defs.h
 
 $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION)
 
@@ -196,9 +196,6 @@ $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN_SHARED)
 $(OUTPUT)libbpf.a: $(BPF_IN_STATIC)
        $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
 
-$(OUTPUT)test_libbpf: test_libbpf.c $(OUTPUT)libbpf.a
-       $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) $^ -lelf -o $@
-
 $(OUTPUT)libbpf.pc:
        $(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \
                -e "s|@LIBDIR@|$(libdir_SQ)|" \
@@ -214,9 +211,9 @@ check_abi: $(OUTPUT)libbpf.so
                     "versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \
                     "Please make sure all LIBBPF_API symbols are"       \
                     "versioned in $(VERSION_SCRIPT)." >&2;              \
-               readelf -s --wide $(OUTPUT)libbpf-in.o |                 \
+               readelf -s --wide $(BPF_IN_SHARED) |                     \
                    cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' |   \
-                   awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}'|   \
+                   awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}'|  \
                    sort -u > $(OUTPUT)libbpf_global_syms.tmp;           \
                readelf -s --wide $(OUTPUT)libbpf.so |                   \
                    grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 |             \
index b20f82e..3f09772 100644 (file)
@@ -171,10 +171,8 @@ struct bpf_program {
                        RELO_DATA,
                } type;
                int insn_idx;
-               union {
-                       int map_idx;
-                       int text_off;
-               };
+               int map_idx;
+               int sym_off;
        } *reloc_desc;
        int nr_reloc;
        int log_level;
@@ -1819,12 +1817,12 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
                        return -LIBBPF_ERRNO__RELOC;
                }
                if (sym->st_value % 8) {
-                       pr_warn("bad call relo offset: %lu\n", sym->st_value);
+                       pr_warn("bad call relo offset: %llu\n", (__u64)sym->st_value);
                        return -LIBBPF_ERRNO__RELOC;
                }
                reloc_desc->type = RELO_CALL;
                reloc_desc->insn_idx = insn_idx;
-               reloc_desc->text_off = sym->st_value / 8;
+               reloc_desc->sym_off = sym->st_value;
                obj->has_pseudo_calls = true;
                return 0;
        }
@@ -1868,6 +1866,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
                reloc_desc->type = RELO_LD64;
                reloc_desc->insn_idx = insn_idx;
                reloc_desc->map_idx = map_idx;
+               reloc_desc->sym_off = 0; /* sym->st_value determines map_idx */
                return 0;
        }
 
@@ -1899,6 +1898,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
        reloc_desc->type = RELO_DATA;
        reloc_desc->insn_idx = insn_idx;
        reloc_desc->map_idx = map_idx;
+       reloc_desc->sym_off = sym->st_value;
        return 0;
 }
 
@@ -3563,8 +3563,8 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
                return -LIBBPF_ERRNO__RELOC;
 
        if (prog->idx == obj->efile.text_shndx) {
-               pr_warn("relo in .text insn %d into off %d\n",
-                       relo->insn_idx, relo->text_off);
+               pr_warn("relo in .text insn %d into off %d (insn #%d)\n",
+                       relo->insn_idx, relo->sym_off, relo->sym_off / 8);
                return -LIBBPF_ERRNO__RELOC;
        }
 
@@ -3599,7 +3599,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
                         prog->section_name);
        }
        insn = &prog->insns[relo->insn_idx];
-       insn->imm += relo->text_off + prog->main_prog_cnt - relo->insn_idx;
+       insn->imm += relo->sym_off / 8 + prog->main_prog_cnt - relo->insn_idx;
        return 0;
 }
 
@@ -3622,31 +3622,26 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
                return 0;
 
        for (i = 0; i < prog->nr_reloc; i++) {
-               if (prog->reloc_desc[i].type == RELO_LD64 ||
-                   prog->reloc_desc[i].type == RELO_DATA) {
-                       bool relo_data = prog->reloc_desc[i].type == RELO_DATA;
-                       struct bpf_insn *insns = prog->insns;
-                       int insn_idx, map_idx;
+               struct reloc_desc *relo = &prog->reloc_desc[i];
 
-                       insn_idx = prog->reloc_desc[i].insn_idx;
-                       map_idx = prog->reloc_desc[i].map_idx;
+               if (relo->type == RELO_LD64 || relo->type == RELO_DATA) {
+                       struct bpf_insn *insn = &prog->insns[relo->insn_idx];
 
-                       if (insn_idx + 1 >= (int)prog->insns_cnt) {
+                       if (relo->insn_idx + 1 >= (int)prog->insns_cnt) {
                                pr_warn("relocation out of range: '%s'\n",
                                        prog->section_name);
                                return -LIBBPF_ERRNO__RELOC;
                        }
 
-                       if (!relo_data) {
-                               insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
+                       if (relo->type != RELO_DATA) {
+                               insn[0].src_reg = BPF_PSEUDO_MAP_FD;
                        } else {
-                               insns[insn_idx].src_reg = BPF_PSEUDO_MAP_VALUE;
-                               insns[insn_idx + 1].imm = insns[insn_idx].imm;
+                               insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
+                               insn[1].imm = insn[0].imm + relo->sym_off;
                        }
-                       insns[insn_idx].imm = obj->maps[map_idx].fd;
-               } else if (prog->reloc_desc[i].type == RELO_CALL) {
-                       err = bpf_program__reloc_text(prog, obj,
-                                                     &prog->reloc_desc[i]);
+                       insn[0].imm = obj->maps[relo->map_idx].fd;
+               } else if (relo->type == RELO_CALL) {
+                       err = bpf_program__reloc_text(prog, obj, relo);
                        if (err)
                                return err;
                }
index 70f1ff4..4934edb 100644 (file)
@@ -19,3 +19,4 @@ tools/lib/bitmap.c
 tools/lib/str_error_r.c
 tools/lib/vsprintf.c
 tools/lib/zalloc.c
+scripts/bpf_helpers_doc.py
index 4a12baa..a2a8ea6 100755 (executable)
@@ -199,7 +199,7 @@ class KUnitMainTest(unittest.TestCase):
                timeout = 3453
                kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock)
                assert self.linux_source_mock.build_reconfig.call_count == 1
-               self.linux_source_mock.run_kernel.assert_called_once_with(timeout=timeout)
+               self.linux_source_mock.run_kernel.assert_called_once_with(build_dir=None, timeout=timeout)
                self.print_mock.assert_any_call(StrContains('Testing complete.'))
 
 if __name__ == '__main__':
index d67f968..b001c60 100644 (file)
@@ -13,6 +13,7 @@ TARGETS += efivarfs
 TARGETS += exec
 TARGETS += filesystems
 TARGETS += filesystems/binderfs
+TARGETS += filesystems/epoll
 TARGETS += firmware
 TARGETS += ftrace
 TARGETS += futex
index 4865116..4196524 100644 (file)
@@ -37,5 +37,6 @@ libbpf.so.*
 test_hashmap
 test_btf_dump
 xdping
+test_cpp
 /no_alu32
 /bpf_gcc
index 085678d..e0fe01d 100644 (file)
@@ -71,7 +71,7 @@ TEST_PROGS_EXTENDED := with_addr.sh \
 # Compile but not part of 'make run_tests'
 TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \
        flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \
-       test_lirc_mode2_user xdping
+       test_lirc_mode2_user xdping test_cpp
 
 TEST_CUSTOM_PROGS = urandom_read
 
@@ -317,6 +317,10 @@ verifier/tests.h: verifier/*.c
 $(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
        $(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
 
+# Make sure we are able to include and link libbpf against c++.
+$(OUTPUT)/test_cpp: test_cpp.cpp $(BPFOBJ)
+       $(CXX) $(CFLAGS) $^ $(LDLIBS) -o $@
+
 EXTRA_CLEAN := $(TEST_CUSTOM_PROGS)                                    \
        prog_tests/tests.h map_tests/tests.h verifier/tests.h           \
        feature $(OUTPUT)/*.o $(OUTPUT)/no_alu32 $(OUTPUT)/bpf_gcc
index 15c7378..b426bf2 100644 (file)
@@ -2,25 +2,21 @@
 /* Copyright (c) 2019 Facebook */
 #include <test_progs.h>
 
-#define PROG_CNT 3
-
-void test_fexit_bpf2bpf(void)
+static void test_fexit_bpf2bpf_common(const char *obj_file,
+                                     const char *target_obj_file,
+                                     int prog_cnt,
+                                     const char **prog_name)
 {
-       const char *prog_name[PROG_CNT] = {
-               "fexit/test_pkt_access",
-               "fexit/test_pkt_access_subprog1",
-               "fexit/test_pkt_access_subprog2",
-       };
        struct bpf_object *obj = NULL, *pkt_obj;
        int err, pkt_fd, i;
-       struct bpf_link *link[PROG_CNT] = {};
-       struct bpf_program *prog[PROG_CNT];
+       struct bpf_link **link = NULL;
+       struct bpf_program **prog = NULL;
        __u32 duration, retval;
        struct bpf_map *data_map;
        const int zero = 0;
-       u64 result[PROG_CNT];
+       u64 *result = NULL;
 
-       err = bpf_prog_load("./test_pkt_access.o", BPF_PROG_TYPE_UNSPEC,
+       err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
                            &pkt_obj, &pkt_fd);
        if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
                return;
@@ -28,7 +24,14 @@ void test_fexit_bpf2bpf(void)
                            .attach_prog_fd = pkt_fd,
                           );
 
-       obj = bpf_object__open_file("./fexit_bpf2bpf.o", &opts);
+       link = calloc(sizeof(struct bpf_link *), prog_cnt);
+       prog = calloc(sizeof(struct bpf_program *), prog_cnt);
+       result = malloc(prog_cnt * sizeof(u64));
+       if (CHECK(!link || !prog || !result, "alloc_memory",
+                 "failed to alloc memory"))
+               goto close_prog;
+
+       obj = bpf_object__open_file(obj_file, &opts);
        if (CHECK(IS_ERR_OR_NULL(obj), "obj_open",
                  "failed to open fexit_bpf2bpf: %ld\n",
                  PTR_ERR(obj)))
@@ -38,7 +41,7 @@ void test_fexit_bpf2bpf(void)
        if (CHECK(err, "obj_load", "err %d\n", err))
                goto close_prog;
 
-       for (i = 0; i < PROG_CNT; i++) {
+       for (i = 0; i < prog_cnt; i++) {
                prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]);
                if (CHECK(!prog[i], "find_prog", "prog %s not found\n", prog_name[i]))
                        goto close_prog;
@@ -56,21 +59,54 @@ void test_fexit_bpf2bpf(void)
              "err %d errno %d retval %d duration %d\n",
              err, errno, retval, duration);
 
-       err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, &result);
+       err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result);
        if (CHECK(err, "get_result",
                  "failed to get output data: %d\n", err))
                goto close_prog;
 
-       for (i = 0; i < PROG_CNT; i++)
+       for (i = 0; i < prog_cnt; i++)
                if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n",
                          result[i]))
                        goto close_prog;
 
 close_prog:
-       for (i = 0; i < PROG_CNT; i++)
+       for (i = 0; i < prog_cnt; i++)
                if (!IS_ERR_OR_NULL(link[i]))
                        bpf_link__destroy(link[i]);
        if (!IS_ERR_OR_NULL(obj))
                bpf_object__close(obj);
        bpf_object__close(pkt_obj);
+       free(link);
+       free(prog);
+       free(result);
+}
+
+static void test_target_no_callees(void)
+{
+       const char *prog_name[] = {
+               "fexit/test_pkt_md_access",
+       };
+       test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o",
+                                 "./test_pkt_md_access.o",
+                                 ARRAY_SIZE(prog_name),
+                                 prog_name);
+}
+
+static void test_target_yes_callees(void)
+{
+       const char *prog_name[] = {
+               "fexit/test_pkt_access",
+               "fexit/test_pkt_access_subprog1",
+               "fexit/test_pkt_access_subprog2",
+       };
+       test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
+                                 "./test_pkt_access.o",
+                                 ARRAY_SIZE(prog_name),
+                                 prog_name);
+}
+
+void test_fexit_bpf2bpf(void)
+{
+       test_target_no_callees();
+       test_target_yes_callees();
 }
index d2af9f0..615f7c6 100644 (file)
@@ -6,28 +6,28 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile __u64 test1_result;
+__u64 test1_result = 0;
 BPF_TRACE_1("fentry/bpf_fentry_test1", test1, int, a)
 {
        test1_result = a == 1;
        return 0;
 }
 
-static volatile __u64 test2_result;
+__u64 test2_result = 0;
 BPF_TRACE_2("fentry/bpf_fentry_test2", test2, int, a, __u64, b)
 {
        test2_result = a == 2 && b == 3;
        return 0;
 }
 
-static volatile __u64 test3_result;
+__u64 test3_result = 0;
 BPF_TRACE_3("fentry/bpf_fentry_test3", test3, char, a, int, b, __u64, c)
 {
        test3_result = a == 4 && b == 5 && c == 6;
        return 0;
 }
 
-static volatile __u64 test4_result;
+__u64 test4_result = 0;
 BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
            void *, a, char, b, int, c, __u64, d)
 {
@@ -35,7 +35,7 @@ BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
        return 0;
 }
 
-static volatile __u64 test5_result;
+__u64 test5_result = 0;
 BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
            __u64, a, void *, b, short, c, int, d, __u64, e)
 {
@@ -44,7 +44,7 @@ BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
        return 0;
 }
 
-static volatile __u64 test6_result;
+__u64 test6_result = 0;
 BPF_TRACE_6("fentry/bpf_fentry_test6", test6,
            __u64, a, void *, b, short, c, int, d, void *, e, __u64, f)
 {
index 525d47d..2d211ee 100644 (file)
@@ -8,7 +8,7 @@ struct sk_buff {
        unsigned int len;
 };
 
-static volatile __u64 test_result;
+__u64 test_result = 0;
 BPF_TRACE_2("fexit/test_pkt_access", test_main,
            struct sk_buff *, skb, int, ret)
 {
@@ -23,7 +23,7 @@ BPF_TRACE_2("fexit/test_pkt_access", test_main,
        return 0;
 }
 
-static volatile __u64 test_result_subprog1;
+__u64 test_result_subprog1 = 0;
 BPF_TRACE_2("fexit/test_pkt_access_subprog1", test_subprog1,
            struct sk_buff *, skb, int, ret)
 {
@@ -56,7 +56,7 @@ struct args_subprog2 {
        __u64 args[5];
        __u64 ret;
 };
-static volatile __u64 test_result_subprog2;
+__u64 test_result_subprog2 = 0;
 SEC("fexit/test_pkt_access_subprog2")
 int test_subprog2(struct args_subprog2 *ctx)
 {
diff --git a/tools/testing/selftests/bpf/progs/fexit_bpf2bpf_simple.c b/tools/testing/selftests/bpf/progs/fexit_bpf2bpf_simple.c
new file mode 100644 (file)
index 0000000..ebc0ab7
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019 Facebook */
+#include <linux/bpf.h>
+#include "bpf_helpers.h"
+#include "bpf_trace_helpers.h"
+
+struct sk_buff {
+       unsigned int len;
+};
+
+__u64 test_result = 0;
+BPF_TRACE_2("fexit/test_pkt_md_access", test_main2,
+           struct sk_buff *, skb, int, ret)
+{
+       int len;
+
+       __builtin_preserve_access_index(({
+               len = skb->len;
+       }));
+       if (len != 74 || ret != 0)
+               return 0;
+
+       test_result = 1;
+       return 0;
+}
+char _license[] SEC("license") = "GPL";
index 2487e98..86db0d6 100644 (file)
@@ -6,28 +6,28 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile __u64 test1_result;
+__u64 test1_result = 0;
 BPF_TRACE_2("fexit/bpf_fentry_test1", test1, int, a, int, ret)
 {
        test1_result = a == 1 && ret == 2;
        return 0;
 }
 
-static volatile __u64 test2_result;
+__u64 test2_result = 0;
 BPF_TRACE_3("fexit/bpf_fentry_test2", test2, int, a, __u64, b, int, ret)
 {
        test2_result = a == 2 && b == 3 && ret == 5;
        return 0;
 }
 
-static volatile __u64 test3_result;
+__u64 test3_result = 0;
 BPF_TRACE_4("fexit/bpf_fentry_test3", test3, char, a, int, b, __u64, c, int, ret)
 {
        test3_result = a == 4 && b == 5 && c == 6 && ret == 15;
        return 0;
 }
 
-static volatile __u64 test4_result;
+__u64 test4_result = 0;
 BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
            void *, a, char, b, int, c, __u64, d, int, ret)
 {
@@ -37,7 +37,7 @@ BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
        return 0;
 }
 
-static volatile __u64 test5_result;
+__u64 test5_result = 0;
 BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
            __u64, a, void *, b, short, c, int, d, __u64, e, int, ret)
 {
@@ -46,7 +46,7 @@ BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
        return 0;
 }
 
-static volatile __u64 test6_result;
+__u64 test6_result = 0;
 BPF_TRACE_7("fexit/bpf_fentry_test6", test6,
            __u64, a, void *, b, short, c, int, d, void *, e, __u64, f,
            int, ret)
index 0d2ec9f..e808791 100644 (file)
@@ -15,8 +15,8 @@ struct {
        __type(value, __u64);
 } data_map SEC(".maps");
 
-static volatile __u64 in_val;
-static volatile __u64 out_val;
+__u64 in_val = 0;
+__u64 out_val = 0;
 
 SEC("raw_tracepoint/sys_enter")
 int test_mmap(void *ctx)
index 3d039e1..1db2623 100644 (file)
@@ -27,8 +27,8 @@ int _version SEC("version") = 1;
        }
 #endif
 
-SEC("test1")
-int process(struct __sk_buff *skb)
+SEC("classifier/test_pkt_md_access")
+int test_pkt_md_access(struct __sk_buff *skb)
 {
        TEST_FIELD(__u8,  len, 0xFF);
        TEST_FIELD(__u16, len, 0xFFFF);
index 2e23361..7fa4595 100644 (file)
@@ -131,6 +131,7 @@ int bpf_testcb(struct bpf_sock_ops *skops)
                                g.bytes_received = skops->bytes_received;
                                g.bytes_acked = skops->bytes_acked;
                        }
+                       g.num_close_events++;
                        bpf_map_update_elem(&global_map, &key, &g,
                                            BPF_ANY);
                }
index 9220747..356351c 100644 (file)
@@ -120,7 +120,7 @@ int check_ancestor_cgroup_ids(int prog_id)
        int err = 0;
        int map_fd;
 
-       expected_ids[0] = 0x100000001;  /* root cgroup */
+       expected_ids[0] = get_cgroup_id("/.."); /* root cgroup */
        expected_ids[1] = get_cgroup_id("");
        expected_ids[2] = get_cgroup_id(CGROUP_PATH);
        expected_ids[3] = 0; /* non-existent cgroup */
index 7bcfa62..6220b95 100644 (file)
@@ -13,5 +13,6 @@ struct tcpbpf_globals {
        __u64 bytes_received;
        __u64 bytes_acked;
        __u32 num_listen;
+       __u32 num_close_events;
 };
 #endif
index 716b4e3..3ae1276 100644 (file)
@@ -16,6 +16,9 @@
 
 #include "test_tcpbpf.h"
 
+/* 3 comes from one listening socket + both ends of the connection */
+#define EXPECTED_CLOSE_EVENTS          3
+
 #define EXPECT_EQ(expected, actual, fmt)                       \
        do {                                                    \
                if ((expected) != (actual)) {                   \
                               "    Actual: %" fmt "\n"         \
                               "  Expected: %" fmt "\n",        \
                               (actual), (expected));           \
-                       goto err;                               \
+                       ret--;                                  \
                }                                               \
        } while (0)
 
 int verify_result(const struct tcpbpf_globals *result)
 {
        __u32 expected_events;
+       int ret = 0;
 
        expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) |
                           (1 << BPF_SOCK_OPS_RWND_INIT) |
@@ -48,15 +52,15 @@ int verify_result(const struct tcpbpf_globals *result)
        EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32);
        EXPECT_EQ(0, result->good_cb_test_rv, PRIu32);
        EXPECT_EQ(1, result->num_listen, PRIu32);
+       EXPECT_EQ(EXPECTED_CLOSE_EVENTS, result->num_close_events, PRIu32);
 
-       return 0;
-err:
-       return -1;
+       return ret;
 }
 
 int verify_sockopt_result(int sock_map_fd)
 {
        __u32 key = 0;
+       int ret = 0;
        int res;
        int rv;
 
@@ -69,9 +73,7 @@ int verify_sockopt_result(int sock_map_fd)
        rv = bpf_map_lookup_elem(sock_map_fd, &key, &res);
        EXPECT_EQ(0, rv, "d");
        EXPECT_EQ(1, res, "d");
-       return 0;
-err:
-       return -1;
+       return ret;
 }
 
 static int bpf_find_map(const char *test, struct bpf_object *obj,
@@ -96,6 +98,7 @@ int main(int argc, char **argv)
        int error = EXIT_FAILURE;
        struct bpf_object *obj;
        int cg_fd = -1;
+       int retry = 10;
        __u32 key = 0;
        int rv;
 
@@ -134,12 +137,20 @@ int main(int argc, char **argv)
        if (sock_map_fd < 0)
                goto err;
 
+retry_lookup:
        rv = bpf_map_lookup_elem(map_fd, &key, &g);
        if (rv != 0) {
                printf("FAILED: bpf_map_lookup_elem returns %d\n", rv);
                goto err;
        }
 
+       if (g.num_close_events != EXPECTED_CLOSE_EVENTS && retry--) {
+               printf("Unexpected number of close events (%d), retrying!\n",
+                      g.num_close_events);
+               usleep(100);
+               goto retry_lookup;
+       }
+
        if (verify_result(&g)) {
                printf("FAILED: Wrong stats\n");
                goto err;
diff --git a/tools/testing/selftests/filesystems/epoll/.gitignore b/tools/testing/selftests/filesystems/epoll/.gitignore
new file mode 100644 (file)
index 0000000..9ae8db4
--- /dev/null
@@ -0,0 +1 @@
+epoll_wakeup_test
diff --git a/tools/testing/selftests/filesystems/epoll/Makefile b/tools/testing/selftests/filesystems/epoll/Makefile
new file mode 100644 (file)
index 0000000..e62f3d4
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+CFLAGS += -I../../../../../usr/include/
+LDFLAGS += -lpthread
+TEST_GEN_PROGS := epoll_wakeup_test
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c b/tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c
new file mode 100644 (file)
index 0000000..37a04da
--- /dev/null
@@ -0,0 +1,3074 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+#include <poll.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include "../../kselftest_harness.h"
+
+struct epoll_mtcontext
+{
+       int efd[3];
+       int sfd[4];
+       int count;
+
+       pthread_t main;
+       pthread_t waiter;
+};
+
+static void signal_handler(int signum)
+{
+}
+
+static void kill_timeout(struct epoll_mtcontext *ctx)
+{
+       usleep(1000000);
+       pthread_kill(ctx->main, SIGUSR1);
+       pthread_kill(ctx->waiter, SIGUSR1);
+}
+
+static void *waiter_entry1a(void *data)
+{
+       struct epoll_event e;
+       struct epoll_mtcontext *ctx = data;
+
+       if (epoll_wait(ctx->efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx->count, 1);
+
+       return NULL;
+}
+
+static void *waiter_entry1ap(void *data)
+{
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext *ctx = data;
+
+       pfd.fd = ctx->efd[0];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx->efd[0], &e, 1, 0) > 0)
+                       __sync_fetch_and_add(&ctx->count, 1);
+       }
+
+       return NULL;
+}
+
+static void *waiter_entry1o(void *data)
+{
+       struct epoll_event e;
+       struct epoll_mtcontext *ctx = data;
+
+       if (epoll_wait(ctx->efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_or(&ctx->count, 1);
+
+       return NULL;
+}
+
+static void *waiter_entry1op(void *data)
+{
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext *ctx = data;
+
+       pfd.fd = ctx->efd[0];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx->efd[0], &e, 1, 0) > 0)
+                       __sync_fetch_and_or(&ctx->count, 1);
+       }
+
+       return NULL;
+}
+
+static void *waiter_entry2a(void *data)
+{
+       struct epoll_event events[2];
+       struct epoll_mtcontext *ctx = data;
+
+       if (epoll_wait(ctx->efd[0], events, 2, -1) > 0)
+               __sync_fetch_and_add(&ctx->count, 1);
+
+       return NULL;
+}
+
+static void *waiter_entry2ap(void *data)
+{
+       struct pollfd pfd;
+       struct epoll_event events[2];
+       struct epoll_mtcontext *ctx = data;
+
+       pfd.fd = ctx->efd[0];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx->efd[0], events, 2, 0) > 0)
+                       __sync_fetch_and_add(&ctx->count, 1);
+       }
+
+       return NULL;
+}
+
+static void *emitter_entry1(void *data)
+{
+       struct epoll_mtcontext *ctx = data;
+
+       usleep(100000);
+       write(ctx->sfd[1], "w", 1);
+
+       kill_timeout(ctx);
+
+       return NULL;
+}
+
+static void *emitter_entry2(void *data)
+{
+       struct epoll_mtcontext *ctx = data;
+
+       usleep(100000);
+       write(ctx->sfd[1], "w", 1);
+       write(ctx->sfd[3], "w", 1);
+
+       kill_timeout(ctx);
+
+       return NULL;
+}
+
+/*
+ *          t0
+ *           | (ew)
+ *          e0
+ *           | (lt)
+ *          s0
+ */
+TEST(epoll1)
+{
+       int efd;
+       int sfd[2];
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 1);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *          t0
+ *           | (ew)
+ *          e0
+ *           | (et)
+ *          s0
+ */
+TEST(epoll2)
+{
+       int efd;
+       int sfd[2];
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 0);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *           t0
+ *            | (ew)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        s0    s2
+ */
+TEST(epoll3)
+{
+       int efd;
+       int sfd[4];
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *           t0
+ *            | (ew)
+ *           e0
+ *     (et) /  \ (et)
+ *        s0    s2
+ */
+TEST(epoll4)
+{
+       int efd;
+       int sfd[4];
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 0);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *          t0
+ *           | (p)
+ *          e0
+ *           | (lt)
+ *          s0
+ */
+TEST(epoll5)
+{
+       int efd;
+       int sfd[2];
+       struct pollfd pfd;
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       ASSERT_EQ(poll(&pfd, 1, 0), 1);
+       ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 1);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       ASSERT_EQ(poll(&pfd, 1, 0), 1);
+       ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 1);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *          t0
+ *           | (p)
+ *          e0
+ *           | (et)
+ *          s0
+ */
+TEST(epoll6)
+{
+       int efd;
+       int sfd[2];
+       struct pollfd pfd;
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       ASSERT_EQ(poll(&pfd, 1, 0), 1);
+       ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 1);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       ASSERT_EQ(poll(&pfd, 1, 0), 0);
+       ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 0);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *           t0
+ *            | (p)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        s0    s2
+ */
+
+TEST(epoll7)
+{
+       int efd;
+       int sfd[4];
+       struct pollfd pfd;
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *           t0
+ *            | (p)
+ *           e0
+ *     (et) /  \ (et)
+ *        s0    s2
+ */
+TEST(epoll8)
+{
+       int efd;
+       int sfd[4];
+       struct pollfd pfd;
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd = epoll_create(1);
+       ASSERT_GE(efd, 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
+
+       pfd.fd = efd;
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 0);
+       EXPECT_EQ(epoll_wait(efd, events, 2, 0), 0);
+
+       close(efd);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll9)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *            | (et)
+ *           s0
+ */
+TEST(epoll10)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 1);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        s0    s2
+ */
+TEST(epoll11)
+{
+       pthread_t emitter;
+       struct epoll_event events[2];
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry2a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], events, 2, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *     (et) /  \ (et)
+ *        s0    s2
+ */
+TEST(epoll12)
+{
+       pthread_t emitter;
+       struct epoll_event events[2];
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], events, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll13)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *            | (et)
+ *           s0
+ */
+TEST(epoll14)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 1);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        s0    s2
+ */
+TEST(epoll15)
+{
+       pthread_t emitter;
+       struct epoll_event events[2];
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry2ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], events, 2, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *     (et) /  \ (et)
+ *        s0    s2
+ */
+TEST(epoll16)
+{
+       pthread_t emitter;
+       struct epoll_event events[2];
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], events, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *          t0
+ *           | (ew)
+ *          e0
+ *           | (lt)
+ *          e1
+ *           | (lt)
+ *          s0
+ */
+TEST(epoll17)
+{
+       int efd[2];
+       int sfd[2];
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *          t0
+ *           | (ew)
+ *          e0
+ *           | (lt)
+ *          e1
+ *           | (et)
+ *          s0
+ */
+TEST(epoll18)
+{
+       int efd[2];
+       int sfd[2];
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *           t0
+ *            | (ew)
+ *           e0
+ *            | (et)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll19)
+{
+       int efd[2];
+       int sfd[2];
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *           t0
+ *            | (ew)
+ *           e0
+ *            | (et)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll20)
+{
+       int efd[2];
+       int sfd[2];
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *          t0
+ *           | (p)
+ *          e0
+ *           | (lt)
+ *          e1
+ *           | (lt)
+ *          s0
+ */
+TEST(epoll21)
+{
+       int efd[2];
+       int sfd[2];
+       struct pollfd pfd;
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *          t0
+ *           | (p)
+ *          e0
+ *           | (lt)
+ *          e1
+ *           | (et)
+ *          s0
+ */
+TEST(epoll22)
+{
+       int efd[2];
+       int sfd[2];
+       struct pollfd pfd;
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *          t0
+ *           | (p)
+ *          e0
+ *           | (et)
+ *          e1
+ *           | (lt)
+ *          s0
+ */
+TEST(epoll23)
+{
+       int efd[2];
+       int sfd[2];
+       struct pollfd pfd;
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 0);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *          t0
+ *           | (p)
+ *          e0
+ *           | (et)
+ *          e1
+ *           | (et)
+ *          s0
+ */
+TEST(epoll24)
+{
+       int efd[2];
+       int sfd[2];
+       struct pollfd pfd;
+       struct epoll_event e;
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 0);
+       EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(sfd[0]);
+       close(sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *            | (lt)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll25)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *            | (lt)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll26)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *            | (et)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll27)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 1);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *            | (et)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll28)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 1);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *            | (lt)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll29)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *            | (lt)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll30)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *            | (et)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll31)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 1);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *            | (et)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll32)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 1);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (ew)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll33)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (ew)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll34)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_or(&ctx.count, 2);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (ew)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll35)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (ew)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll36)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_or(&ctx.count, 2);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (ew)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll37)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       pfd.fd = ctx.efd[1];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
+                       __sync_fetch_and_add(&ctx.count, 1);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (ew)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll38)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       pfd.fd = ctx.efd[1];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
+                       __sync_fetch_and_or(&ctx.count, 2);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (ew)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll39)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       pfd.fd = ctx.efd[1];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
+                       __sync_fetch_and_add(&ctx.count, 1);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (ew)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll40)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       pfd.fd = ctx.efd[1];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
+                       __sync_fetch_and_or(&ctx.count, 2);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (p)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll41)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (p)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll42)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_or(&ctx.count, 2);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (p)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll43)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *    (ew) |    | (p)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll44)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_or(&ctx.count, 2);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (p)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll45)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       pfd.fd = ctx.efd[1];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
+                       __sync_fetch_and_add(&ctx.count, 1);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (p)
+ *         |   e0
+ *          \  / (lt)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll46)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_or(&ctx.count, 2);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (p)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (lt)
+ *           s0
+ */
+TEST(epoll47)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       pfd.fd = ctx.efd[1];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
+                       __sync_fetch_and_add(&ctx.count, 1);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *        t0   t1
+ *     (p) |    | (p)
+ *         |   e0
+ *          \  / (et)
+ *           e1
+ *            | (et)
+ *           s0
+ */
+TEST(epoll48)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
+               __sync_fetch_and_or(&ctx.count, 2);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+}
+
+/*
+ *           t0
+ *            | (ew)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll49)
+{
+       int efd[3];
+       int sfd[4];
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       efd[2] = epoll_create(1);
+       ASSERT_GE(efd[2], 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(efd[2]);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *           t0
+ *            | (ew)
+ *           e0
+ *     (et) /  \ (et)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll50)
+{
+       int efd[3];
+       int sfd[4];
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       efd[2] = epoll_create(1);
+       ASSERT_GE(efd[2], 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 0);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(efd[2]);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *           t0
+ *            | (p)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll51)
+{
+       int efd[3];
+       int sfd[4];
+       struct pollfd pfd;
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       efd[2] = epoll_create(1);
+       ASSERT_GE(efd[2], 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(efd[2]);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *           t0
+ *            | (p)
+ *           e0
+ *     (et) /  \ (et)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll52)
+{
+       int efd[3];
+       int sfd[4];
+       struct pollfd pfd;
+       struct epoll_event events[2];
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
+
+       efd[0] = epoll_create(1);
+       ASSERT_GE(efd[0], 0);
+
+       efd[1] = epoll_create(1);
+       ASSERT_GE(efd[1], 0);
+
+       efd[2] = epoll_create(1);
+       ASSERT_GE(efd[2], 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
+
+       events[0].events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
+
+       events[0].events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
+
+       ASSERT_EQ(write(sfd[1], "w", 1), 1);
+       ASSERT_EQ(write(sfd[3], "w", 1), 1);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 1);
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
+
+       pfd.fd = efd[0];
+       pfd.events = POLLIN;
+       EXPECT_EQ(poll(&pfd, 1, 0), 0);
+       EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 0);
+
+       close(efd[0]);
+       close(efd[1]);
+       close(efd[2]);
+       close(sfd[0]);
+       close(sfd[1]);
+       close(sfd[2]);
+       close(sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll53)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       ctx.efd[2] = epoll_create(1);
+       ASSERT_GE(ctx.efd[2], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.efd[2]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (ew)
+ *           e0
+ *     (et) /  \ (et)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll54)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       ctx.efd[2] = epoll_create(1);
+       ASSERT_GE(ctx.efd[2], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.efd[2]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll55)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       ctx.efd[2] = epoll_create(1);
+       ASSERT_GE(ctx.efd[2], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.efd[2]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *     (ew) \  / (p)
+ *           e0
+ *     (et) /  \ (et)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll56)
+{
+       pthread_t emitter;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       ctx.efd[2] = epoll_create(1);
+       ASSERT_GE(ctx.efd[2], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
+               __sync_fetch_and_add(&ctx.count, 1);
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.efd[2]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *      (p) \  / (p)
+ *           e0
+ *     (lt) /  \ (lt)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll57)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       ctx.efd[2] = epoll_create(1);
+       ASSERT_GE(ctx.efd[2], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       pfd.fd = ctx.efd[0];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[0], &e, 1, 0) > 0)
+                       __sync_fetch_and_add(&ctx.count, 1);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.efd[2]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+/*
+ *        t0    t1
+ *      (p) \  / (p)
+ *           e0
+ *     (et) /  \ (et)
+ *        e1    e2
+ *    (lt) |     | (lt)
+ *        s0    s2
+ */
+TEST(epoll58)
+{
+       pthread_t emitter;
+       struct pollfd pfd;
+       struct epoll_event e;
+       struct epoll_mtcontext ctx = { 0 };
+
+       signal(SIGUSR1, signal_handler);
+
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
+       ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
+
+       ctx.efd[0] = epoll_create(1);
+       ASSERT_GE(ctx.efd[0], 0);
+
+       ctx.efd[1] = epoll_create(1);
+       ASSERT_GE(ctx.efd[1], 0);
+
+       ctx.efd[2] = epoll_create(1);
+       ASSERT_GE(ctx.efd[2], 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
+
+       e.events = EPOLLIN;
+       ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
+
+       e.events = EPOLLIN | EPOLLET;
+       ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
+
+       ctx.main = pthread_self();
+       ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
+       ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
+
+       pfd.fd = ctx.efd[0];
+       pfd.events = POLLIN;
+       if (poll(&pfd, 1, -1) > 0) {
+               if (epoll_wait(ctx.efd[0], &e, 1, 0) > 0)
+                       __sync_fetch_and_add(&ctx.count, 1);
+       }
+
+       ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
+       EXPECT_EQ(ctx.count, 2);
+
+       if (pthread_tryjoin_np(emitter, NULL) < 0) {
+               pthread_kill(emitter, SIGUSR1);
+               pthread_join(emitter, NULL);
+       }
+
+       close(ctx.efd[0]);
+       close(ctx.efd[1]);
+       close(ctx.efd[2]);
+       close(ctx.sfd[0]);
+       close(ctx.sfd[1]);
+       close(ctx.sfd[2]);
+       close(ctx.sfd[3]);
+}
+
+TEST_HARNESS_MAIN
index 36fb59f..1a52f28 100644 (file)
@@ -3,6 +3,8 @@
 # description: ftrace - stacktrace filter command
 # flags: instance
 
+[ ! -f set_ftrace_filter ] && exit_unsupported
+
 echo _do_fork:stacktrace >> set_ftrace_filter
 
 grep -q "_do_fork:stacktrace:unlimited" set_ftrace_filter
index 86a1f07..71fa3f4 100644 (file)
@@ -15,6 +15,11 @@ if [ $NP -eq 1 ] ;then
   exit_unresolved
 fi
 
+if ! grep -q "function" available_tracers ; then
+  echo "Function trace is not enabled"
+  exit_unsupported
+fi
+
 ORIG_CPUMASK=`cat tracing_cpumask`
 
 do_reset() {
index 86986c4..5d45505 100644 (file)
@@ -46,6 +46,9 @@ reset_events_filter() { # reset all current setting filters
 }
 
 reset_ftrace_filter() { # reset all triggers in set_ftrace_filter
+    if [ ! -f set_ftrace_filter ]; then
+      return 0
+    fi
     echo > set_ftrace_filter
     grep -v '^#' set_ftrace_filter | while read t; do
        tr=`echo $t | cut -d: -f2`
@@ -93,7 +96,7 @@ initialize_ftrace() { # Reset ftrace to initial-state
     disable_events
     [ -f set_event_pid ] && echo > set_event_pid
     [ -f set_ftrace_pid ] && echo > set_ftrace_pid
-    [ -f set_ftrace_filter ] && echo | tee set_ftrace_*
+    [ -f set_ftrace_notrace ] && echo > set_ftrace_notrace
     [ -f set_graph_function ] && echo | tee set_graph_*
     [ -f stack_trace_filter ] && echo > stack_trace_filter
     [ -f kprobe_events ] && echo > kprobe_events
index 5862eee..6e3dbe5 100644 (file)
@@ -20,9 +20,9 @@ while read i; do
   test $N -eq 256 && break
 done
 
-L=`wc -l kprobe_events`
-if [ $L -ne $N ]; then
-  echo "The number of kprobes events ($L) is not $N"
+L=`cat kprobe_events | wc -l`
+if [ $L -ne 256 ]; then
+  echo "The number of kprobes events ($L) is not 256"
   exit_fail
 fi
 
index 1221240..3f2aee1 100644 (file)
@@ -21,10 +21,10 @@ grep -q "snapshot()" README || exit_unsupported # version issue
 
 echo "Test expected snapshot action failure"
 
-echo 'hist:keys=comm:onmatch(sched.sched_wakeup).snapshot()' >> /sys/kernel/debug/tracing/events/sched/sched_waking/trigger && exit_fail
+echo 'hist:keys=comm:onmatch(sched.sched_wakeup).snapshot()' >> events/sched/sched_waking/trigger && exit_fail
 
 echo "Test expected save action failure"
 
-echo 'hist:keys=comm:onmatch(sched.sched_wakeup).save(comm,prio)' >> /sys/kernel/debug/tracing/events/sched/sched_waking/trigger && exit_fail
+echo 'hist:keys=comm:onmatch(sched.sched_wakeup).save(comm,prio)' >> events/sched/sched_waking/trigger && exit_fail
 
 exit_xfail
index 064a284..c80007a 100644 (file)
@@ -16,7 +16,7 @@ grep -q "onchange(var)" README || exit_unsupported # version issue
 
 echo "Test onchange action"
 
-echo 'hist:keys=comm:newprio=prio:onchange($newprio).save(comm,prio) if comm=="ping"' >> /sys/kernel/debug/tracing/events/sched/sched_waking/trigger
+echo 'hist:keys=comm:newprio=prio:onchange($newprio).save(comm,prio) if comm=="ping"' >> events/sched/sched_waking/trigger
 
 ping $LOCALHOST -c 3
 nice -n 1 ping $LOCALHOST -c 3
index 18fff69..f546c1b 100644 (file)
@@ -23,9 +23,9 @@ grep -q "snapshot()" README || exit_unsupported # version issue
 
 echo "Test snapshot action"
 
-echo 1 > /sys/kernel/debug/tracing/events/sched/enable
+echo 1 > events/sched/enable
 
-echo 'hist:keys=comm:newprio=prio:onchange($newprio).save(comm,prio):onchange($newprio).snapshot() if comm=="ping"' >> /sys/kernel/debug/tracing/events/sched/sched_waking/trigger
+echo 'hist:keys=comm:newprio=prio:onchange($newprio).save(comm,prio):onchange($newprio).snapshot() if comm=="ping"' >> events/sched/sched_waking/trigger
 
 ping $LOCALHOST -c 3
 nice -n 1 ping $LOCALHOST -c 3
index 18e1c79..fb4733f 100755 (executable)
@@ -9,7 +9,7 @@
 #
 #   #!/bin/sh
 #   SPDX-License-Identifier: GPL-2.0+
-#   $(dirname $0)/../kselftest_module.sh "description" module_name
+#   $(dirname $0)/../kselftest/module.sh "description" module_name
 #
 # Example: tools/testing/selftests/lib/printf.sh
 
index ec7e481..31f7c2a 100755 (executable)
@@ -3,6 +3,7 @@
 # Prefix all lines with "# ", unbuffered. Command being piped in may need
 # to have unbuffering forced with "stdbuf -i0 -o0 -e0 $cmd".
 use strict;
+use IO::Handle;
 
 binmode STDIN;
 binmode STDOUT;
index 84de7bc..a8d20cb 100644 (file)
@@ -79,6 +79,7 @@ run_one()
                if [ $rc -eq $skip_rc ]; then   \
                        echo "not ok $test_num $TEST_HDR_MSG # SKIP"
                elif [ $rc -eq $timeout_rc ]; then \
+                       echo "#"
                        echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT"
                else
                        echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
index 46abcae..13e5ef6 100644 (file)
 #define TLS_PAYLOAD_MAX_LEN 16384
 #define SOL_TLS 282
 
-#ifndef ENOTSUPP
-#define ENOTSUPP 524
-#endif
-
 FIXTURE(tls_basic)
 {
        int fd, cfd;
@@ -1205,11 +1201,11 @@ TEST(non_established) {
        /* TLS ULP not supported */
        if (errno == ENOENT)
                return;
-       EXPECT_EQ(errno, ENOTSUPP);
+       EXPECT_EQ(errno, ENOTCONN);
 
        ret = setsockopt(sfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
        EXPECT_EQ(ret, -1);
-       EXPECT_EQ(errno, ENOTSUPP);
+       EXPECT_EQ(errno, ENOTCONN);
 
        ret = getsockname(sfd, &addr, &len);
        ASSERT_EQ(ret, 0);
index 98da7a5..fa02c4d 100644 (file)
@@ -1,8 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for mount selftests.
-CFLAGS = -Wall -lcap -O2
+CFLAGS = -Wall -O2
+LDLIBS = -lcap
 
-TEST_PROGS := run_tests.sh
+TEST_PROGS := safesetid-test.sh
 TEST_GEN_FILES := safesetid-test
 
 include ../lib.mk
index 8f40c6e..0c4d506 100644 (file)
@@ -213,7 +213,8 @@ static void test_setuid(uid_t child_uid, bool expect_success)
        }
 
        if (cpid == 0) {            /* Code executed by child */
-               setuid(child_uid);
+               if (setuid(child_uid) < 0)
+                       exit(EXIT_FAILURE);
                if (getuid() == child_uid)
                        exit(EXIT_SUCCESS);
                else
@@ -291,8 +292,10 @@ int main(int argc, char **argv)
 
        // First test to make sure we can write userns mappings from a user
        // that doesn't have any restrictions (as long as it has CAP_SETUID);
-       setuid(NO_POLICY_USER);
-       setgid(NO_POLICY_USER);
+       if (setuid(NO_POLICY_USER) < 0)
+               die("Error with set uid(%d)\n", NO_POLICY_USER);
+       if (setgid(NO_POLICY_USER) < 0)
+               die("Error with set gid(%d)\n", NO_POLICY_USER);
 
        // Take away all but setid caps
        drop_caps(true);
@@ -306,8 +309,10 @@ int main(int argc, char **argv)
                die("test_userns failed when it should work\n");
        }
 
-       setuid(RESTRICTED_PARENT);
-       setgid(RESTRICTED_PARENT);
+       if (setuid(RESTRICTED_PARENT) < 0)
+               die("Error with set uid(%d)\n", RESTRICTED_PARENT);
+       if (setgid(RESTRICTED_PARENT) < 0)
+               die("Error with set gid(%d)\n", RESTRICTED_PARENT);
 
        test_setuid(ROOT_USER, false);
        test_setuid(ALLOWED_CHILD1, true);
index 24543a3..4a753a4 100644 (file)
@@ -16,9 +16,6 @@ override c_flags = $(UAPI_CFLAGS) -Wp,-MD,$(depfile) -I$(objtree)/usr/include
 # Please consider to fix the header first.
 #
 # Sorted alphabetically.
-header-test- += asm/ipcbuf.h
-header-test- += asm/msgbuf.h
-header-test- += asm/sembuf.h
 header-test- += asm/shmbuf.h
 header-test- += asm/signal.h
 header-test- += asm/ucontext.h
@@ -40,7 +37,6 @@ header-test- += linux/omapfb.h
 header-test- += linux/patchkey.h
 header-test- += linux/phonet.h
 header-test- += linux/reiserfs_xattr.h
-header-test- += linux/scc.h
 header-test- += linux/sctp.h
 header-test- += linux/signal.h
 header-test- += linux/sysctl.h